Pandas 是用于数据分析 Python 的软件库,提供了大量快速便捷地处理数据的函数和方法。
本文翻译自官方文档 10 Minutes to pandas 。
导入所需的软件包:
1 | In [1]: import pandas as pd |
对象创建
请参阅数据结构介绍部分。
通过传递列表创建 Series,其中 pandas 会创建默认的整数索引:
1 | In [4]: s = pd.Series([1,3,5,np.nan,6,8]) |
通过传递具有日期时间索引和标签列的 numpy 数组,创建 DataFrame:
1 | In [6]: dates = pd.date_range('20130101', periods=6) |
通过传递类似序列结构的字典,来创建 DataFrame:
1 | In [10]: df2 = pd.DataFrame({ 'A' : 1., |
通过特定的 dtypes 方法,查看每列的数据类型:
1 | In [12]: df2.dtypes |
使用 IPython 时,按 TAB
可以自动补全:
1 | In [13]: df2.<TAB> |
数据查看
请参阅基础部分。
查看顶部和底部的行:
1 | In [14]: df.head() |
显示索引,列和 numpy 数据:
1 | In [16]: df.index |
显示数据的快速统计概要:
1 | In [19]: df.describe() |
对数据进行转置:
1 | In [20]: df.T |
按轴排序:
1 | In [21]: df.sort_index(axis=1, ascending=False) |
按值排序:
1 | In [22]: df.sort_values(by='B') |
选择
注意虽然标准 Python / Numpy 表达式非常直观并且可以方便地用于交互式工作,但在代码中,推荐使用优化的数据访问方法
.at
、.iat
、.loc
、.iloc
和.ix
。
获取
选择单列,将会返回一个 Series,相当于 df.A
:
1 | In [23]: df['A'] |
通过 []
对行进行切片:
1 | In [24]: df[0:3] |
按标签选择
请参阅按标签选择。
使用标签获取单行:
1 | In [26]: df.loc[dates[0]] |
通过标签在多个轴上选择:
1 | In [27]: df.loc[:,['A','B']] |
使用标签的起止端点进行切片:
1 | In [28]: df.loc['20130102':'20130104',['A','B']] |
返回降维的对象:
1 | In [29]: df.loc['20130102',['A','B']] |
按位置取值:
1 | In [30]: df.loc[dates[0],'A'] |
快速按位置取值(同上个方法):
1 | In [31]: df.at[dates[0],'A'] |
按位置选择
请参阅按位置选择。
通过传递整数位置进行选择:
1 | In [32]: df.iloc[3] |
使用整数进行切片,类似于 numpy / python:
1 | In [33]: df.iloc[3:5,0:2] |
指定整数列表取行列,类似于 numpy / python:
1 | In [34]: df.iloc[[1,2,4],[0,2]] |
对行进行切片:
1 | In [35]: df.iloc[1:3,:] |
对列进行切片:
1 | In [36]: df.iloc[:,1:3] |
按位置取值:
1 | In [37]: df.iloc[1,1] |
快速按位置取值(同上个方法):
1 | In [38]: df.iat[1,1] |
布尔索引
对满足布尔条件的单列元素取值:
1 | In [39]: df[df.A > 0] |
对满足布尔条件的 DataFrame 取值:
1 | In [40]: df[df > 0] |
使用 isin()
方法进行过滤:
1 | In [41]: df2 = df.copy() |
设置
设置新列,自动按索引排列数据:
1 | In [45]: s1 = pd.Series([1,2,3,4,5,6], index=pd.date_range('20130102', periods=6)) |
按标签设置新的值:
1 | In [48]: df.at[dates[0],'A'] = 0 |
按位置设置新的值:
1 | In [49]: df.iat[0,1] = 0 |
通过分配一个 numpy 数组设置新的值:
1 | In [50]: df.loc[:,'D'] = np.array([5] * len(df)) |
上述操作结果如下:
1 | In [51]: df |
通过 where
设置值:
1 | In [52]: df2 = df.copy() |
数据缺失
pandas 使用 np.nan
来表示缺失的数据,缺失的数据默认不参与任何计算。
请参阅数据缺失部分。
reindex()
允许更改/添加/删除指定轴上的索引,并返回数据的副本:
1 | In [55]: df1 = df.reindex(index=dates[0:4], columns=list(df.columns) + ['E']) |
删除任何具有缺失数据的行:
1 | In [58]: df1.dropna(how='any') |
对缺失数据进行填充:
1 | In [59]: df1.fillna(value=5) |
获取值为 nan
的布尔掩码:
1 | In [60]: pd.isna(df1) |
操作
请参阅操作的基本部分。
统计
丢失的数据不参与一般操作。
平均值统计(默认为轴 0):
1 | In [61]: df.mean() |
平均值统计(轴 1):
1 | In [62]: df.mean(1) |
具有广播功能,可以对于拥有不同维度、可以对齐的对象进行操作(同 numpy 数组):
1 | In [63]: s = pd.Series([1,3,5,np.nan,6,8], index=dates).shift(2) |
应用函数
将函数应用于数据:
1 | In [66]: df.apply(np.cumsum) |
直方图
请参阅直方图和离散化。
1 | In [68]: s = pd.Series(np.random.randint(0, 7, size=10)) |
字符串方法
Series 的 str
属性具有字符串处理方法,便于对数组中的每个元素进行操作,如下所示。str
的模式匹配通常默认使用正则表达式。
请参阅向量化的字符串方法。
1 | In [71]: s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat']) |
合并
Concat
pandas 提供了大量方法,可以方便地对 Series,DataFrame 和 Panel 对象进行合并操作。
请参阅合并部分。
使用 concat()
合并 pandas 对象:
1 | In [73]: df = pd.DataFrame(np.random.randn(10, 4)) |
Join
以 SQL 的样式合并。请参阅数据库样式的加入。
1 | In [77]: left = pd.DataFrame({'key': ['foo', 'foo'], 'lval': [1, 2]}) |
另一个例子如下:
1 | In [82]: left = pd.DataFrame({'key': ['foo', 'bar'], 'lval': [1, 2]}) |
Append
将新行连接到 DataFrame 上。见附加。
1 | In [87]: df = pd.DataFrame(np.random.randn(8, 4), columns=['A','B','C','D']) |
分组
“group by” 指的是涉及一个或多个以下步骤的过程:
- 根据一些规则将数据分组
- 对于每组数据分别应用函数
- 将结果组合成一个数据结构
请参见分组部分。
1 | In [91]: df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', |
分组,然后应用函数 sum
:
1 | In [93]: df.groupby('A').sum() |
按多列分组会生成分层索引,然后应用函数 sum
:
1 | In [94]: df.groupby(['A','B']).sum() |
重塑
请参阅分层索引和重塑。
Stack
1 | In [95]: tuples = list(zip(*[['bar', 'bar', 'baz', 'baz', |
stack()
方法对 DataFrame 的列进行“压缩”。
1 | In [100]: stacked = df2.stack() |
对于 “堆叠的” DataFrame 或 Series(多索引),stack()
的逆操作是 unstack()
,默认拆下最后一层:
1 | In [102]: stacked.unstack() |
透视表
请参阅透视表。
1 | In [105]: df = pd.DataFrame({'A' : ['one', 'one', 'two', 'three'] * 3, |
可以从上述数据轻松生成透视表:
1 | In [107]: pd.pivot_table(df, values='D', index=['A', 'B'], columns=['C']) |
时间序列
pandas 在对频率转换进行重新采样时拥有简单、强大且高效的功能(如将按秒采样的数据转换为按5分钟为单位进行采样的数据)。这种操作常见于(但并不限于)金融领域。
请参阅时间序列部分。
1 | In [108]: rng = pd.date_range('1/1/2012', periods=100, freq='S') |
时区表示:
1 | In [111]: rng = pd.date_range('3/6/2012 00:00', periods=5, freq='D') |
时区转换:
1 | In [116]: ts_utc.tz_convert('US/Eastern') |
时间跨度转换:
1 | In [117]: rng = pd.date_range('1/1/2012', periods=5, freq='M') |
周期和时间戳之间的转换使得可以使用一些方便的算术函数。
下面的例子将季度结束时间从 11 月份转换为该季度最后一个月的上午 9 点:
1 | In [123]: prng = pd.period_range('1990Q1', '2000Q4', freq='Q-NOV') |
Categorical
pandas 可以在 DataFrame 中支持 Categorical 类型的数据。
请参阅Categorical 介绍和Categorical 的API文档。
1 | In [127]: df = pd.DataFrame({"id":[1,2,3,4,5,6], "raw_grade":['a', 'b', 'b', 'a', 'a', 'e']}) |
将原始的 grade
转换为 Categorical 类型:
1 | In [128]: df["grade"] = df["raw_grade"].astype("category") |
将 Categorical 类型数据重命名为更有意义的名称:
1 | In [130]: df["grade"].cat.categories = ["very good", "good", "very bad"] |
对类别进行重新排序,增加缺失的类别:
1 | In [131]: df["grade"] = df["grade"].cat.set_categories(["very bad", "bad", "medium", "good", "very good"]) |
排序是按照 Categorical 顺序进行,而不是按照字典顺序进行:
1 | In [133]: df.sort_values(by="grade") |
对列进行排序,空的类别也会包含在其中:
1 | In [134]: df.groupby("grade").size() |
绘图
请参阅绘制文档。
1 | In [135]: ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000)) |
对于 DataFrame 来说,plot
是一种将所有列及其标签进行绘制的简便方法:
1 | In [138]: df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index, |
数据导入/导出
CSV
1 | In [141]: df.to_csv('foo.csv') |
1 | In [142]: pd.read_csv('foo.csv') |
HDF5
使用 HDFStores 进行读写。
写入 HDF5 存储:
1 | In [143]: df.to_hdf('foo.h5','df') |
读取 HDF5 存储:
1 | In [144]: pd.read_hdf('foo.h5','df') |
Excel
使用 MS Excel 进行读写。
写入 Excel 文件:
1 | In [145]: df.to_excel('foo.xlsx', sheet_name='Sheet1') |
读取 Excel 文件:
1 | In [146]: pd.read_excel('foo.xlsx', 'Sheet1', index_col=None, na_values=['NA']) |