使用python在本地电脑上快速处理数据
大数据一般是在“云”上玩的,但“云”都是要钱的,而且数据上上下下的也比较麻烦。所以,在本地电脑上快速处理数据的技能还是要的。
pandas
在比赛中学到的一个工具,本地可以在亿级别的数据上进行聚合等操作。内部的数据包括:
•Series:一维数组,每个元素有一个标签
•DataFrame:二维表格,可以看做Series的集合
•Panel:三维数据
数据的初始化
我们可以通过构造函数来初始化,从下面的代码中可以想象得到数据是样子:
frompandasimportSeries,DataFrame s=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(基础方法):
importpandasaspd df1=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])
合并完的结果为:
ABCD 0A0B0C0D0 1A1B1C1D1 2A2B2C2D2 3A3B3C3D3 4A4B4C4D4 5A5B5C5D5 6A6B6C6D6 7A7B7C7D7
其参数含义如下:
•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(将两个表的数据进行融合):
importpandasaspd left=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不一样的地方):
ABkeyCD 0A0B0K0C0D0 1A1B1K1C1D1 2A2B2K2C2D2 3A3B3K3C3D3
方法的参数有:
•left、right:将要进行关联的两个表
•how:关联方式(left、right、inner、outer)
•on:实现关联的列,不传应该是找相同列名
•left_on、right_on:分别为left、right的关联列,在列名不同时使用
•left_index、right_index:是否用索引来关联
•sort:排序
•suffixes:后缀
•copy:是否复制数据
对应的简化版本为join方法:
importpandasaspd left=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)
输出为:
ABCD K0A0B0C0D0 K1A1B1C1D1 K2A2B2C2D2 K3A3B3C3D3
数据的查询和分析
基本查询
精确查看单个位置数据的方法:
•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)是最最基本的一个分析手段,看个例子:
importpandasaspd importnumpyasnp df=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'])
可以对各组进行遍历:
forname,groupinresult: print(name) print(group)
对分组的结果可以过滤:
df.groupby('A').B.filter(lambdax: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)可以对各个分组分别计算:
importpandasaspd importnumpyasnp df=pd.DataFrame(data={ 'A':[1,1,3], 'B':[4,5,6], 'C':[7,np.nan,9]}) print(df.groupby('A')['B'].transform(lambdax:x-x.mean()))
输出结果为:
0-0.5 10.5 20.0 Name: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))
主要集中在数组、矩阵的处理上!是很多工具的基础。