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 相关文章推荐
python字典多条件排序方法实例
Jun 30 Python
用python实现面向对像的ASP程序实例
Nov 10 Python
Python 3.6 性能测试框架Locust安装及使用方法(详解)
Oct 11 Python
python中获得当前目录和上级目录的实现方法
Oct 12 Python
Python学习之用pygal画世界地图实例
Dec 07 Python
Python变量类型知识点总结
Feb 18 Python
Tensorflow实现在训练好的模型上进行测试
Jan 20 Python
Python是什么 Python的用处
May 26 Python
深入浅析pycharm中 Make available to all projects的含义
Sep 15 Python
Django返回HTML文件的实现方法
Sep 17 Python
python基于opencv实现人脸识别
Jan 04 Python
python字典的元素访问实例详解
Jul 21 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表单转换textarea换行符的方法
2010/09/10 PHP
php中使用session_set_save_handler()函数把session保存到MySQL数据库实例
2014/11/06 PHP
5款适合PHP使用的HTML编辑器推荐
2015/07/03 PHP
PHP中error_reporting()用法详解
2015/08/31 PHP
yii2实现根据时间搜索的方法
2016/05/25 PHP
php实现快速对二维数组某一列进行组装的方法小结
2019/12/04 PHP
JQuery Tips(2) 关于$()包装集你不知道的
2009/12/14 Javascript
优化javascript的执行速度
2010/01/23 Javascript
基于jquery的放大镜效果
2012/05/30 Javascript
浅谈JavaScript正则表达式分组匹配
2015/04/10 Javascript
TypeError document.getElementById(...) is null错误原因
2015/05/18 Javascript
Bootstrap每天必学之简单入门
2015/11/19 Javascript
原生JavaScript实现动态省市县三级联动下拉框菜单实例代码
2016/02/03 Javascript
JQuery控制图片由中心点逐渐放大效果
2016/06/26 Javascript
js 动态生成json对象、时时更新json对象的方法
2016/12/02 Javascript
React注册倒计时功能的实现
2018/09/06 Javascript
Bootstrap实现模态框效果
2019/09/30 Javascript
探索浏览器页面关闭window.close()的使用详解
2020/08/21 Javascript
[54:24]Optic vs TNC 2018国际邀请赛小组赛BO2 第二场
2018/08/18 DOTA
Python实现的检测网站挂马程序
2014/11/30 Python
Python数组并集交集补集代码实例
2020/02/18 Python
使用matplotlib动态刷新指定曲线实例
2020/04/23 Python
基于python模拟bfs和dfs代码实例
2020/11/19 Python
jupyter notebook远程访问不了的问题解决方法
2021/01/11 Python
Otel.com:折扣酒店预订
2017/08/24 全球购物
聪明的粉丝购买门票的地方:TickPick
2018/03/09 全球购物
英国的潮牌鞋履服饰商店:size?
2019/03/26 全球购物
Stutterheim瑞典:瑞典高级外套时装品牌
2019/06/24 全球购物
会议邀请书范文
2014/02/02 职场文书
20年同学聚会感言
2014/02/03 职场文书
鼓励运动员的广播稿
2014/02/08 职场文书
四查四看整改措施
2014/09/19 职场文书
员工教育培训协议书
2014/09/27 职场文书
婚前协议书怎么写,才具有法律效力呢 ?
2019/06/28 职场文书
Python3 多线程(连接池)操作MySQL插入数据
2021/06/09 Python
使用@Value值注入及配置文件组件扫描
2021/07/09 Java/Android