侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

使用python在本地电脑上快速处理数据

Python  /  管理员 发布于 7年前   157

大数据一般是在“云”上玩的,但“云”都是要钱的,而且数据上上下下的也比较麻烦。所以,在本地电脑上快速处理数据的技能还是要的。

pandas

在比赛中学到的一个工具,本地可以在亿级别的数据上进行聚合等操作。内部的数据包括:
• Series:一维数组,每个元素有一个标签
• DataFrame:二维表格,可以看做Series的集合
• Panel:三维数据

数据的初始化

我们可以通过构造函数来初始化,从下面的代码中可以想象得到数据是样子:

from pandas import Series, DataFrames = Series(data=[1, 2, 3], index=['a', 'b', 'c'])df = DataFrame(  data=[    [1, 2, 3],    [4, 5, 6],    [7, 8, 9]  ],  index=['i1', 'i2', 'i3'],  columns=['c1', 'c2', 'c3'])

如果源数据是格式比较好的CSV(或者是自己加工生成的中间数据),可以直接读取:
df = pandas.read_csv("../volume.csv", header=0)

数据的更新

更新结构

在定义完成之后可以对行、列进行增减(增减数据、修改结构):
• 增加列: • df.insert(3, 'new_column', [4, 7, 10])
• df['c4'] = [4, 7, 10]

• 删除列 • df.pop('c1')
• df = df.drop('c1', axis=1)

• 增加行:一般不要动态的增加行,据说新能不高 • df.loc['i4'] = [10, 11, 12]
• df.loc['i4'] = {'c1': 10, 'c2': 11, 'c3': 12}

• 删除行: • df = df.drop('i1', axis=0)

更新数据

我们可以精确修改单个位置的值:
• df['c1']['i1'] = 77
• df.ix[1, 2] = 66

合并数据

数据很多时候分布在不同的DataFrame中,要使用需要将他们进行合并,第一种方式是concat(基础方法):

import pandas as pddf1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],          'B': ['B0', 'B1', 'B2', 'B3'],          'C': ['C0', 'C1', 'C2', 'C3'],          'D': ['D0', 'D1', 'D2', 'D3']},          index=[0, 1, 2, 3])df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],          'B': ['B4', 'B5', 'B6', 'B7'],          'C': ['C4', 'C5', 'C6', 'C7'],          'D': ['D4', 'D5', 'D6', 'D7']},          index=[4, 5, 6, 7])result = pd.concat([df1, df2])

合并完的结果为:

  A  B  C  D0 A0 B0 C0 D01 A1 B1 C1 D12 A2 B2 C2 D23 A3 B3 C3 D34 A4 B4 C4 D45 A5 B5 C5 D56 A6 B6 C6 D67 A7 B7 C7 D7

其参数含义如下:
• objs :合并的数据(Series、DataFrame)
• axis :合并轴方向,行(0)、列(1)
• join :关联类型(inner、outer)
• join_axes :结果行,eg: pd.concat([df1, df2], axis=1, join_axes=[pd.Int64Index([1, 2, 3])])
• ignore_index :是否忽略objs中传入的索引
• keys :来自不同表的index,每个表一个(ignore_index=True时不管用)
• levels :不同层次的索引
• names :不同层次的索引的名字
• verify_integrity :检查是否包含重复项(有一定的代价)
• copy :是否赋值数据

另一个相对简化点的操作是append(简化版,好像没啥特别的):
result = df1.append(df2)

接着来看重点方法merge(将两个表的数据进行融合):

import pandas as pdleft = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],           'A': ['A0', 'A1', 'A2', 'A3'],           'B': ['B0', 'B1', 'B2', 'B3']})right = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],           'C': ['C0', 'C1', 'C2', 'C3'],           'D': ['D0', 'D1', 'D2', 'D3']})result = pd.merge(left, right, on='key')print(result)

结果为(注意观察与concat不一样的地方): 

  A  B key  C  D0 A0 B0 K0 C0 D01 A1 B1 K1 C1 D12 A2 B2 K2 C2 D23 A3 B3 K3 C3 D3

方法的参数有:
• left、right :将要进行关联的两个表
• how :关联方式(left、right、inner、outer)
• on :实现关联的列,不传应该是找相同列名
• left_on、right_on :分别为left、right的关联列,在列名不同时使用
• left_index、right_index :是否用索引来关联
• sort :排序
• suffixes :后缀
• copy :是否复制数据

对应的简化版本为join方法:

import pandas as pdleft = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],           'B': ['B0', 'B1', 'B2', 'B3']},          index=['K0', 'K1', 'K2', 'K3'])right = pd.DataFrame({'C': ['C0', 'C1', 'C2', 'C3'],           'D': ['D0', 'D1', 'D2', 'D3']},           index=['K0', 'K1', 'K2', 'K3'])result = left.join(right)print(result)

输出为:

   A  B  C  DK0 A0 B0 C0 D0K1 A1 B1 C1 D1K2 A2 B2 C2 D2K3 A3 B3 C3 D3

数据的查询和分析

基本查询

精确查看单个位置数据的方法:
• df['c1']['i1']
• df.loc['i1']['c1'] (先行后列)
• df.iloc[1] (下标操作)
• df.ix['i1'][1] 或 df.ix[0, 2] (随意使用下标或名称)

通过切片的操作批量取出数据:
• df.loc['i1':'i2', ['c1', 'c2']]
• df.iloc[1:3, [1, 2]]
• df.ix[1:3, 0:2]

查看某行或某列:
• 行: df.loc['i1']
• 列: df['c1']

分组

分组(GroupBy)是最最基本的一个分析手段,看个例子:

import pandas as pdimport numpy as npdf = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],          'B': ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],          'C': np.random.randn(8),          'D': np.random.randn(8)})result = df.groupby(['A'])print(result.get_group('foo'))

其他分组形式:
• df.groupby('A')
• df.groupby(['A', 'B'])
• df.groupby(group_func, axis=1)
• df.groupby(level=0)
• df.groupby([pd.Grouper(level=0), 'A'])

可以对各组进行遍历:

for name, group in result:  print(name)  print(group)

对分组的结果可以过滤:

df.groupby('A').B.filter(lambda x : len(x) > 1)

进一步对各个分组进行计算(结果太直观,就不写了):
• df.groupby(['A', 'B']).sum()
• df.groupby(['A', 'B']).sum().reset_index()
• df.groupby(['A', 'B']).aggregate(np.sum)
• df.groupby(['A', 'B']).agg(np.sum)
• df.groupby(['A', 'B']).agg([np.sum, np.mean])
• df.groupby(['A', 'B']).agg([np.sum, np.mean]).rename(columns={'sum': 's', 'mean': 'm'})
• df.groupby(['A', 'B']).agg({'C': np.sum, 'D': np.mean})
• df.groupby(['A', 'B']).agg({'C': 'sum', 'D': 'mean'})

利用transform(类似的还有apply)可以对各个分组分别计算:

import pandas as pdimport numpy as npdf = pd.DataFrame(data={  'A': [1, 1, 3],  'B': [4, 5, 6],  'C': [7, np.nan, 9]})print(df.groupby('A')['B'].transform(lambda x : x - x.mean()))

输出结果为:

0  -0.51  0.52  0.0Name: B, dtype: float64


类似的,可以在分组上使用窗口函数:
• rolling
• resample
• expanding

条件过滤

用一些常用的构造方式,可以有类似SQL的开发效率��:
• tips[tips['time'] == 'Dinner'].head(5)
• tips[(tips['time'] == 'Dinner') & (tips['tip'] > 5.00)]
• tips[(tips['size'] >= 5) | (tips['total_bill'] > 45)]
• frame[frame['col2'].isnull()]
• frame[frame['col1'].notnull()]

最后,如果想图形化看在PyCharm里面需要搞个 plt.show() (其他的IDE并不清楚)。

numpy

比较早接触的numpy,总体上来看处理数据比自带类型方便些:
• np.array([[1, 2, 3, 4],[4, 5, 6, 7], [7, 8, 9, 10]])
• np.array((5, 6, 7, 8))

主要集中在数组、矩阵的处理上!是很多工具的基础。


  • 上一条:
    Tornado协程在python2.7如何返回值(实现方法)
    下一条:
    python2.7 mayavi 安装图文教程(推荐)
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go语言中实现字符串可逆性压缩及解压缩功能(0个评论)
    • 使用go + gin + jwt + qrcode实现网站生成登录二维码在app中扫码登录功能(0个评论)
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客