操作
统计
此类操作默认排除缺失数据
# 求平均值
print(df.mean())
print("------")
# 指定求平均值的轴
print(df.mean(1))
print("------")
# 创建Series对象s,以dates为索引并平移2个位置
s = pd.Series([1,3,5,np.nan,6,8], index=dates).shift(2)
print(s)
print("------")
# 从df中逐列减去s(若有NaN则得NaN)
print(df.sub(s, axis='index'))
应用
对DataFrame中的数据应用函数。
# 逐行累加
print(df.apply(np.cumsum))
print("------")
# 每列的最大值减最小值
print(df.apply(lambda x: x.max() - x.min()))
字符
Series
对象的str
属性具有一系列字符处理方法,可以很轻松地操作数组的每个元素。
s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat'])
print(s.str.lower())
合并
连接
Pandas在join/merge两中情境下提供了支持多种方式,基于逻辑/集合运算和代数运算来连接Series,DataFrame和Panel对象。
df = pd.DataFrame(np.random.randn(10, 4))
print(df)
print("------")
# 拆分成块
pieces = [df[:3], df[3:7], df[7:]]
# 重新连接,可得初始数组
print(pd.concat(pieces))
增补
df = pd.DataFrame(np.random.randn(8, 4), columns=['A','B','C','D'])
print(df)
print("------")
# 将索引为3的行增补到整个DataFrame最后
s = df.iloc[3]
print(df.append(s, ignore_index=True))
组合
“组合”包含以下步骤:
- 基于一定标准将数据分组
- 对每个部分分别应用函数
- 把结果汇合到数据结构中
# 新建DataFrame对象df
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)})
print(df)
print("------")
# 对'A'列进行合并并应用.sum()函数
print(df.groupby('A').sum())
print("------")
# 对'A', 'B'两列分别合并形成层级结构,再应用.sum()函数
print(df.groupby(['A','B']).sum())
重塑
tuples = list(zip(*[['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'], ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]))
# 多重索引
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
df = pd.DataFrame(np.random.randn(8, 2), index=index, columns=['A', 'B'])
df2 = df[:4]
print(df2)
print("------")
# .stack()方法将DataFrame的列“压缩”了一级
stacked = df2.stack()
print(stacked)
对于已经层次化的,具有多重索引的DataFrame或Series,
stack()
的逆操作是
unstack()
——默认将最后一级“去层次化”。
print(stacked.unstack())
print("------")
print(stacked.unstack(1))
print("------")
print(stacked.unstack(0))
数据透视表
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)})
print(df)
print("------")
# 生成数据透视表
print(pd.pivot_table(df, values='D', index=['A', 'B'], columns=['C']))
时间序列
Pandas提供了简单、强力且有效的工具,可以在频率转换中进行重采样(比如从秒级数据中提取5分钟一更新的数据)。这在金融工程中应用甚广,当然也不仅限于金融领域。
rng = pd.date_range('3/6/2012 00:00', periods=5, freq='D')
ts = pd.Series(np.random.randn(len(rng)), rng)
print(ts)
print("------")
# 设定国际时区标准
ts_utc = ts.tz_localize('UTC')
print(ts_utc)
print("------")
# 切换时区
print(ts_utc.tz_convert('US/Eastern'))
周期和时间戳之间的转换让我们可以方便的使用一些算术运算。比如下面的例子,我们把一个以季度为单位的时间序列转换为按日期表示。
prng = pd.period_range('1990Q1', '2000Q4', freq='Q-NOV')
ts = pd.Series(np.random.randn(len(prng)), prng)
print(ts.head())
print("------")
ts.index = (prng.asfreq('M', 'e') + 1).asfreq('H', 's') + 9
print(ts.head())
分类
df = pd.DataFrame({"id":[1,2,3,4,5,6], "raw_grade":['a', 'b', 'b', 'a', 'a', 'e']})
# 将原始记录转换为分类类型
df["grade"] = df["raw_grade"].astype("category")
print(df["grade"])
将类别重命名为更有意义的字样
df["grade"].cat.categories = ["very good", "good", "very bad"]
# 重排类别同时添加上缺失的类别名称
df["grade"] = df["grade"].cat.set_categories(["very bad", "bad", "medium", "good", "very good"])
print(df["grade"])
print("------")
# 排序在各分类中分别进行
print(df.sort_values(by="grade"))
print("------")
# 对类别列分组可以显示空类
print(df.groupby("grade").size())
绘图
# 生成一串随机序列
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
# 求累加和
ts = ts.cumsum()
# 输出图象
ts.plot()
# 生成一个4列的DataFrame,每列1000行,并逐列累加
df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index, columns=['A', 'B', 'C', 'D'])
df = df.cumsum()
df.plot(); plt.legend(loc='best')
获取数据输入/输出
CSV
# 输出至.csv文件
df.to_csv('haha.csv')
# 从.csv文件中读取数据
pd.read_csv('haha.csv')
Excel
# 输出至.xlsx文件
df.to_excel('haha.xlsx', sheet_name='Sheet1')
# 从.xlsx文件中读取数据
pd.read_excel('foo.xlsx', 'Sheet1', index_col=None, na_values=['NA'])
('haha.csv')