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


Posted in Python onJune 22, 2017

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

pandas

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

数据的初始化

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

from pandas import Series, 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(基础方法):

import pandas as pd

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])

合并完的结果为:

A  B  C  D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
4 A4 B4 C4 D4
5 A5 B5 C5 D5
6 A6 B6 C6 D6
7 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 pd

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不一样的地方): 

A  B key  C  D
0 A0 B0 K0 C0 D0
1 A1 B1 K1 C1 D1
2 A2 B2 K2 C2 D2
3 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 pd

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)

输出为:

A  B  C  D
K0 A0 B0 C0 D0
K1 A1 B1 C1 D1
K2 A2 B2 C2 D2
K3 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 pd
import numpy as np

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'])

可以对各组进行遍历:

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 pd
import numpy as np

df = 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.5
1  0.5
2  0.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))

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

Python 相关文章推荐
利用Python和OpenCV库将URL转换为OpenCV格式的方法
Mar 27 Python
python制作花瓣网美女图片爬虫
Oct 28 Python
Python操作SQLite数据库的方法详解【导入,创建,游标,增删改查等】
Jul 11 Python
python 获取url中的参数列表实例
Dec 18 Python
Django model update的多种用法介绍
Mar 28 Python
django框架模型层功能、组成与用法分析
Jul 30 Python
Python学习笔记之Django创建第一个数据库模型的方法
Aug 07 Python
详解Python可视化神器Yellowbrick使用
Nov 11 Python
python、Matlab求定积分的实现
Nov 20 Python
详解Python高阶函数
Aug 15 Python
python 算法题——快乐数的多种解法
May 27 Python
健身房被搭讪?用python写了个小米计时器助人为乐
Jun 08 Python
python2.7 mayavi 安装图文教程(推荐)
Jun 22 #Python
python 字符串转列表 list 出现\ufeff的解决方法
Jun 22 #Python
Python查询IP地址归属完整代码
Jun 21 #Python
Python批量查询域名是否被注册过
Jun 21 #Python
Python图片裁剪实例代码(如头像裁剪)
Jun 21 #Python
Python编程实战之Oracle数据库操作示例
Jun 21 #Python
Python获取SQLite查询结果表列名的方法
Jun 21 #Python
You might like
php下关于Cannot use a scalar value as an array的解决办法
2010/08/08 PHP
WordPress开发中用于获取近期文章的PHP函数使用解析
2016/01/05 PHP
PHP错误处理函数
2016/04/03 PHP
php 使用html5实现多文件上传实例
2016/10/24 PHP
Centos 6.5系统下编译安装PHP 7.0.13的方法
2016/12/19 PHP
PHP new static 和 new self详解
2017/02/19 PHP
PHP 多进程与信号中断实现多任务常驻内存管理实例方法
2019/10/04 PHP
js不是基础的基础
2006/12/24 Javascript
syntaxhighlighter 使用方法
2007/07/02 Javascript
利用jQuery的$.event.fix函数统一浏览器event事件处理
2009/12/21 Javascript
jQuery的Ajax时无响应数据的解决方法
2010/05/25 Javascript
ASP.NET中AJAX 调用实例代码
2012/05/03 Javascript
jquery创建并行对象或者合并对象的实现代码
2012/10/10 Javascript
基于JavaScript实现 获取鼠标点击位置坐标的方法
2013/04/12 Javascript
js和as的稳定传值问题解决
2013/07/14 Javascript
举例讲解JavaScript substring()的使用方法
2015/11/09 Javascript
JS 对java返回的json格式的数据处理方法
2016/12/05 Javascript
基于Node的React图片上传组件实现实例代码
2017/05/10 Javascript
javascript函数的节流[throttle]与防抖[debounce]
2017/11/15 Javascript
vue scroller返回页面记住滚动位置的实例代码
2018/01/29 Javascript
Python实现抓取网页并且解析的实例
2014/09/20 Python
pandas groupby 分组取每组的前几行记录方法
2018/04/20 Python
python实现自动发送邮件
2018/06/20 Python
Python3实现从排序数组中删除重复项算法分析
2019/04/03 Python
numpy中的ndarray方法和属性详解
2019/05/27 Python
通过Python编写一个简单登录功能过程解析
2019/09/04 Python
python 实现目录复制的三种小结
2019/12/04 Python
pycharm 的Structure界面设置操作
2021/02/05 Python
Pycharm 如何一键加引号的方法步骤
2021/02/05 Python
财务管理专业自荐信范文
2013/12/24 职场文书
同事打架检讨书
2014/02/04 职场文书
走近毛泽东观后感
2015/06/04 职场文书
董事长年会致辞
2015/07/29 职场文书
2017寒假社会实践心得体会范文
2016/01/14 职场文书
JavaScript利用html5新方法操作元素类名详解
2021/11/27 Javascript
mysql 索引的数据结构为什么要采用B+树
2022/04/26 MySQL