Python科学计算之Pandas详解


Posted in Python onJanuary 15, 2017

起步

Pandas最初被作为金融数据分析工具而开发出来,因此 pandas 为时间序列分析提供了很好的支持。 Pandas 的名称来自于面板数据(panel data)和python数据分析 (data analysis) 。panel data是经济学中关于多维数据集的一个术语,在Pandas中也提供了panel的数据类型。

在我看来,对于 Numpy 以及 Matplotlib ,Pandas可以帮助创建一个非常牢固的用于数据挖掘与分析的基础。而Scipy当然是另一个主要的也十分出色的科学计算库。

安装与导入

通过pip进行安装: pip install pandas

导入:

import pandas as pd

Pandas的数据类型

Pandas基于两种数据类型: series 与 dataframe 。

Series

一个series是一个一维的数据类型,其中每一个元素都有一个标签。类似于Numpy中元素带标签的数组。其中,标签可以是数字或者字符串。

# coding: utf-8
import numpy as np
import pandas as pd

s = pd.Series([1, 2, 5, np.nan, 6, 8])
print s

输出:

0 1.0
1 2.0
2 5.0
3 NaN
4 6.0
5 8.0
dtype: float64

DataFrame

一个dataframe是一个二维的表结构。Pandas的dataframe可以存储许多种不同的数据类型,并且每一个坐标轴都有自己的标签。你可以把它想象成一个series的字典项。

创建一个 DateFrame:

#创建日期索引序列 
dates = pd.date_range('20130101', periods=6)
#创建Dataframe,其中 index 决定索引序列,columns 决定列名
df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD'))
print df

输出:

A  B  C  D
2013-01-01 -0.334482 0.746019 -2.205026 -0.803878
2013-01-02 2.007879 1.559073 -0.527997 0.950946
2013-01-03 -1.053796 0.438214 -0.027664 0.018537
2013-01-04 -0.208744 -0.725155 -0.395226 -0.268529
2013-01-05 0.080822 -1.215433 -0.785030 0.977654
2013-01-06 -0.126459 0.426328 -0.474553 -1.968056

字典创建 DataFrame

df2 = pd.DataFrame({ 'A' : 1.,
   'B' : pd.Timestamp('20130102'),
   'C' : pd.Series(1,index=list(range(4)),dtype='float32'),
   'D' : np.array([3] * 4,dtype='int32'),
   'E' : pd.Categorical(["test","train","test","train"]),
   'F' : 'foo' })

输出:

A  B C D E F
0 1 2013-01-02 1 3 test foo
1 1 2013-01-02 1 3 train foo
2 1 2013-01-02 1 3 test foo
3 1 2013-01-02 1 3 train foo

将文件数据导入Pandas

df = pd.read_csv("Average_Daily_Traffic_Counts.csv", header = 0)
df.head()

Python科学计算之Pandas详解

数据源可以是 英国政府数据 或 美国政府数据 来获取数据源。当然, Kaggle 是另一个好用的数据源。

选择/切片

# 选择单独的一列,返回 Serires,与 df.A 效果相当。
df['A']

# 位置切片
df[0:3]

# 索引切片
df['20130102':'20130104']

# 通过标签选择
df.loc[dates[0]]

# 对多个轴同时通过标签进行选择
df.loc[:,['A','B']]

# 获得某一个单元的数据
df.loc[dates[0],'A']
# 或者
df.at[dates[0],'A'] # 速度更快的做法

# 通过位置进行选择
df.iloc[3]

# 切片
df.iloc[3:5,0:2]

# 列表选择
df.iloc[[1,2,4],[0,2]]

# 获得某一个单元的数据
df.iloc[1,1]
# 或者
df.iat[1,1] # 更快的做法

# 布尔索引
df[df.A > 0]

# 获得大于零的项的数值
df[df > 0]

# isin 过滤
df2[df2['E'].isin(['two','four'])]

赋值

# 新增一列,根据索引排列
s1 = pd.Series([1,2,3,4,5,6], index=pd.date_range('20130102', periods=6))
df['F'] = s1

# 缺省项
# 在 pandas 中使用 np.nan 作为缺省项的值。
df1 = df.reindex(index=dates[0:4], columns=list(df.columns) + ['E'])
df1.loc[dates[0]:dates[1],'E'] = 1

# 删除所有带有缺省项的行
df1.dropna(how='any')

# 填充缺省项
df1.fillna(value=5)

# 获得缺省项的布尔掩码
pd.isnull(df1)

观察操作

# 观察开头的数据
df.head()

# 观察末尾的数据
df.tail(3)

# 显示索引
df.index

# 显示列
df.columns

# 显示底层 numpy 结构
df.values

# DataFrame 的基本统计学属性预览
df.describe()
"""
  A  B  C  D
count 6.000000 6.000000 6.000000 6.000000 #数量
mean 0.073711 -0.431125 -0.687758 -0.233103 #平均值
std 0.843157 0.922818 0.779887 0.973118 #标准差
min -0.861849 -2.104569 -1.509059 -1.135632 #最小值
25% -0.611510 -0.600794 -1.368714 -1.076610 #正态分布 25%
50% 0.022070 -0.228039 -0.767252 -0.386188 #正态分布 50%
75% 0.658444 0.041933 -0.034326 0.461706 #正态分布 75%
max 1.212112 0.567020 0.276232 1.071804 #最大值
"""

# 转置
df.T

# 根据某一轴的索引进行排序
df.sort_index(axis=1, ascending=False)

# 根据某一列的数值进行排序
df.sort(columns='B')

统计

# 求平均值
df.mean()
"""
A -0.004474
B -0.383981
C -0.687758
D 5.000000
F 3.000000
dtype: float64
"""

# 指定轴上的平均值
df.mean(1)

# 不同维度的 pandas 对象也可以做运算,它会自动进行对应,shift 用来做对齐操作。
s = pd.Series([1,3,5,np.nan,6,8], index=dates).shift(2)
"""
2013-01-01 NaN
2013-01-02 NaN
2013-01-03 1
2013-01-04 3
2013-01-05 5
2013-01-06 NaN
Freq: D, dtype: float64
"""

# 对不同维度的 pandas 对象进行减法操作
df.sub(s, axis='index')
"""
   A  B  C D F
2013-01-01 NaN NaN NaN NaN NaN
2013-01-02 NaN NaN NaN NaN NaN
2013-01-03 -1.861849 -3.104569 -1.494929 4 1
2013-01-04 -2.278445 -3.706771 -4.039575 2 0
2013-01-05 -5.424972 -4.432980 -4.723768 0 -1
2013-01-06 NaN NaN NaN NaN NaN
"""

函数应用

# 累加
df.apply(np.cumsum)

直方图

s = pd.Series(np.random.randint(0, 7, size=10))
s.value_counts()
"""
4 5
6 2
2 2
1 1
dtype: int64
String Methods
"""

字符处理

s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat'])
s.str.lower()
"""
0 a
1 b
2 c
3 aaba
4 baca
5 NaN
6 caba
7 dog
8 cat
dtype: object
"""

合并

使用 concat() 连接 pandas 对象:

df = pd.DataFrame(np.random.randn(10, 4))
"""
  0  1  2  3
0 -0.548702 1.467327 -1.015962 -0.483075
1 1.637550 -1.217659 -0.291519 -1.745505
2 -0.263952 0.991460 -0.919069 0.266046
3 -0.709661 1.669052 1.037882 -1.705775
4 -0.919854 -0.042379 1.247642 -0.009920
5 0.290213 0.495767 0.362949 1.548106
6 -1.131345 -0.089329 0.337863 -0.945867
7 -0.932132 1.956030 0.017587 -0.016692
8 -0.575247 0.254161 -1.143704 0.215897
9 1.193555 -0.077118 -0.408530 -0.862495
"""

pieces = [df[:3], df[3:7], df[7:]]
pd.concat(pieces)
"""
  0  1  2  3
0 -0.548702 1.467327 -1.015962 -0.483075
1 1.637550 -1.217659 -0.291519 -1.745505
2 -0.263952 0.991460 -0.919069 0.266046
3 -0.709661 1.669052 1.037882 -1.705775
4 -0.919854 -0.042379 1.247642 -0.009920
5 0.290213 0.495767 0.362949 1.548106
6 -1.131345 -0.089329 0.337863 -0.945867
7 -0.932132 1.956030 0.017587 -0.016692
8 -0.575247 0.254161 -1.143704 0.215897
9 1.193555 -0.077118 -0.408530 -0.862495
"""

join 合并:

left = pd.DataFrame({'key': ['foo', 'foo'], 'lval': [1, 2]})
right = pd.DataFrame({'key': ['foo', 'foo'], 'rval': [4, 5]})
pd.merge(left, right, on='key')
"""
 key lval rval
0 foo 1 4
1 foo 1 5
2 foo 2 4
3 foo 2 5
"""

追加

在 dataframe 数据后追加行

df = pd.DataFrame(np.random.randn(8, 4), columns=['A','B','C','D'])
s = df.iloc[3]
df.append(s, ignore_index=True)

分组

分组常常意味着可能包含以下的几种的操作中一个或多个

  • 依据一些标准分离数据
  • 对组单独地应用函数
  • 将结果合并到一个数据结构中
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)})

# 对单个分组应用函数,数据被分成了 bar 组与 foo 组,分别计算总和。
df.groupby('A').sum()

# 依据多个列分组会构成一个分级索引
df.groupby(['A','B']).sum()
"""
   C  D
A B   
bar one -1.814470 2.395985
 three -0.595447 0.166599
 two -0.392670 -0.136473
foo one -1.195665 -0.616981
 three 1.928123 -1.623033
 two 2.414034 1.600434
"""

数据透视表

df = pd.DataFrame({'A' : ['one', 'one', 'two', 'three'] * 3,
   'B' : ['A', 'B', 'C'] * 4,
   'C' : ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'] * 2,
   'D' : np.random.randn(12),
   'E' : np.random.randn(12)})

# 生成数据透视表
pd.pivot_table(df, values='D', index=['A', 'B'], columns=['C'])
"""
C  bar foo
A B   
one A -0.773723 1.418757
 B -0.029716 -1.879024
 C -1.146178 0.314665
three A 1.006160 NaN
 B NaN -1.035018
 C 0.648740 NaN
two A NaN 0.100900
 B -1.170653 NaN
 C NaN 0.536826
"""

时间序列

pandas 拥有既简单又强大的频率变换重新采样功能,下面的例子从 1次/秒 转换到了 1次/5分钟:

rng = pd.date_range('1/1/2012', periods=100, freq='S')
ts = pd.Series(np.random.randint(0, 500, len(rng)), index=rng)
ts.resample('5Min', how='sum')
"""
2012-01-01 25083
Freq: 5T, dtype: int32
"""

# 本地化时区表示
rng = pd.date_range('3/6/2012 00:00', periods=5, freq='D')
ts = pd.Series(np.random.randn(len(rng)), rng)
"""
2012-03-06 0.464000
2012-03-07 0.227371
2012-03-08 -0.496922
2012-03-09 0.306389
2012-03-10 -2.290613
Freq: D, dtype: float64
"""

ts_utc = ts.tz_localize('UTC')
"""
2012-03-06 00:00:00+00:00 0.464000
2012-03-07 00:00:00+00:00 0.227371
2012-03-08 00:00:00+00:00 -0.496922
2012-03-09 00:00:00+00:00 0.306389
2012-03-10 00:00:00+00:00 -2.290613
Freq: D, dtype: float64
"""

# 转换为周期
ps = ts.to_period()

# 转换为时间戳
ps.to_timestamp()

分类

df = pd.DataFrame({"id":[1,2,3,4,5,6], "raw_grade":['a', 'b', 'b', 'a', 'a', 'e']})

# 将 raw_grades 转换成 Categoricals 类型
df["grade"] = df["raw_grade"].astype("category")
df["grade"]
"""
0 a
1 b
2 b
3 a
4 a
5 e
Name: grade, dtype: category
Categories (3, object): [a, b, e]
"""

# 重命名分类
df["grade"] = df["grade"].cat.set_categories(["very bad", "bad", "medium", "good", "very good"])

# 根据分类的顺序对数据进行排序
df.sort("grade")
"""
 id raw_grade  grade
5 6   e very bad
1 2   b  good
2 3   b  good
0 1   a very good
3 4   a very good
4 5   a very good
"""

作图

ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts = ts.cumsum()
ts.plot()

数据IO

# 从 csv 文件读取数据
pd.read_csv('foo.csv')

# 保存到 csv 文件
df.to_csv('foo.csv')

# 读取 excel 文件
pd.read_excel('foo.xlsx', 'Sheet1', index_col=None, na_values=['NA'])

# 保存到 excel 文件
df.to_excel('foo.xlsx', sheet_name='Sheet1')

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家学习或者使用python能带来一定的帮助,如果有疑问大家可以留言交流。

Python 相关文章推荐
在Django的模型中添加自定义方法的示例
Jul 21 Python
PHP网页抓取之抓取百度贴吧邮箱数据代码分享
Apr 13 Python
在python 中实现运行多条shell命令
Jan 07 Python
对Python3 * 和 ** 运算符详解
Feb 16 Python
python调用并链接MATLAB脚本详解
Jul 05 Python
Python使用itchat模块实现简单的微信控制电脑功能示例
Aug 26 Python
Django自带日志 settings.py文件配置方法
Aug 30 Python
浅谈keras中自定义二分类任务评价指标metrics的方法以及代码
Jun 11 Python
python实现取余操作的简单实例
Aug 16 Python
python向xls写入数据(包括合并,边框,对齐,列宽)
Feb 02 Python
正确的理解和使用Django信号(Signals)
Apr 14 Python
如何正确理解python装饰器
Jun 15 Python
使用pyecharts无法import Bar的解决方案
Apr 23 #Python
详解Python3中字符串中的数字提取方法
Jan 14 #Python
win7上python2.7连接mysql数据库的方法
Jan 14 #Python
python实现字符串连接的三种方法及其效率、适用场景详解
Jan 13 #Python
python实现读取并显示图片的两种方法
Jan 13 #Python
Python中的连接符(+、+=)示例详解
Jan 13 #Python
Python中datetime模块参考手册
Jan 13 #Python
You might like
php mysql数据库操作类
2008/06/04 PHP
关于PHP堆栈与列队的学习
2013/06/21 PHP
smarty内置函数foreach用法实例
2015/01/22 PHP
thinkphp3.2实现跨控制器调用其他模块的方法
2017/03/14 PHP
PHP通过文件路径获取文件名的实例代码
2018/10/14 PHP
浅谈javascript的原型继承
2012/07/25 Javascript
原始XMLHttpRequest方法详情回顾
2013/11/28 Javascript
jquery trigger伪造a标签的click事件取代window.open方法
2014/06/23 Javascript
浅谈js中的闭包
2015/03/16 Javascript
vue-router项目实战总结篇
2018/02/11 Javascript
详解Vue2.5+迁移至Typescript指南
2019/08/01 Javascript
微信小程序引入模块中wxml、wxss、js的方法示例
2019/08/09 Javascript
javascript this指向相关问题及改变方法
2020/11/19 Javascript
Python中用于计算对数的log()方法
2015/05/15 Python
Python lxml模块安装教程
2015/06/02 Python
Python 正则表达式实现计算器功能
2017/04/29 Python
用Eclipse写python程序
2018/02/10 Python
Python切片操作实例分析
2018/03/16 Python
在Python中使用gRPC的方法示例
2018/08/08 Python
Python设计模式之状态模式原理与用法详解
2019/01/15 Python
Django 用户认证组件使用详解
2019/07/23 Python
python模块常用用法实例详解
2019/10/17 Python
python实现取余操作的简单实例
2020/08/16 Python
pycharm 添加解释器的方法步骤
2020/08/31 Python
Django框架安装及项目创建过程解析
2020/09/14 Python
通过实例解析Python文件操作实现步骤
2020/09/21 Python
如何快速一次性卸载所有python包(第三方库)呢
2020/10/20 Python
python 用opencv实现图像修复和图像金字塔
2020/11/27 Python
介绍一下linux的文件系统
2015/10/06 面试题
退伍老兵事迹材料
2014/01/31 职场文书
《一株紫丁香》教学反思
2014/02/19 职场文书
生态养殖创业计划书
2014/05/06 职场文书
乡村教师党员四风问题对照检查材料思想汇报
2014/10/08 职场文书
二胎满月酒致辞
2015/07/29 职场文书
师德师风培训感言
2015/08/03 职场文书
重阳节主题班会
2015/08/17 职场文书