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 相关文章推荐
分享15个最受欢迎的Python开源框架
Jul 13 Python
Python和GO语言实现的消息摘要算法示例
Mar 10 Python
python实现多线程的方式及多条命令并发执行
Jun 07 Python
Python 专题三 字符串的基础知识
Mar 19 Python
使用Python通过win32 COM打开Excel并添加Sheet的方法
May 02 Python
在cmder下安装ipython以及环境的搭建
Oct 19 Python
Python Pexpect库的简单使用方法
Jan 29 Python
对python中的控制条件、循环和跳出详解
Jun 24 Python
python tkinter之顶层菜单、弹出菜单实例
Mar 04 Python
Python3通过chmod修改目录或文件权限的方法示例
Jun 08 Python
浅谈Python中的模块
Jun 10 Python
详解python实现可视化的MD5、sha256哈希加密小工具
Sep 14 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 is_file 判断给定文件名是否为一个正常的文件
2010/05/10 PHP
smarty简单分页的实现方法
2014/10/27 PHP
PHP接收json 并将接收数据插入数据库的实现代码
2015/12/01 PHP
Zend Framework入门教程之Zend_Session会话操作详解
2016/12/08 PHP
Laravel 5.2 文档 数据库 ―― 起步介绍
2019/10/21 PHP
JavaScript 函数参数是传值(byVal)还是传址(byRef) 分享
2013/07/02 Javascript
判断客户浏览器是否支持cookie的示例代码
2013/12/23 Javascript
Javascript前端UI框架Kit使用指南之kitjs事件管理
2014/11/28 Javascript
JavaScript实现文字与图片拖拽效果的方法
2015/02/16 Javascript
JavaScript实现自动对页面上敏感词进行屏蔽的方法
2015/07/27 Javascript
jquery+ajax实现注册实时验证实例详解
2015/12/08 Javascript
javascript如何定义对象数组
2016/06/07 Javascript
jQuery编写设置和获取颜色的插件
2017/01/09 Javascript
详解nodeJS之路径PATH模块
2017/05/31 NodeJs
JavaScript字符串检索字符的方法
2017/06/23 Javascript
JavaScript判断变量名是否存在数组中的实例
2017/12/28 Javascript
Vue源码解析之数据响应系统的使用
2019/04/24 Javascript
JS实现关闭小广告特效
2021/01/29 Javascript
浅析vue-router中params和query的区别
2019/12/24 Javascript
vue axios封装httpjs,接口公用配置拦截操作
2020/08/11 Javascript
js简单粗暴的发布订阅示例代码
2021/01/23 Javascript
如何准确判断请求是搜索引擎爬虫(蜘蛛)发出的请求
2015/10/13 Python
将pip源更换到国内镜像的详细步骤
2019/04/07 Python
pygame实现打字游戏
2021/02/19 Python
python3 配置logging日志类的操作
2020/04/08 Python
viagogo英国票务平台:演唱会、体育比赛、戏剧门票
2017/03/24 全球购物
JPA面试常见问题
2016/11/14 面试题
什么是反射
2012/03/17 面试题
四查四看剖析材料
2014/02/14 职场文书
党的群众路线教育实践活动宣传标语口号
2014/06/06 职场文书
党员目标管理责任书
2014/07/25 职场文书
绿色环保倡议书
2015/04/28 职场文书
2016入党积极分子党课培训心得体会
2016/01/06 职场文书
2016年“9.22”世界无车日活动小结
2016/04/05 职场文书
2019年市场部个人述职报告(三篇)
2019/10/23 职场文书
总结Python变量的相关知识
2021/06/28 Python