# 一文掌握Pandas量化进阶
# 这节课学习Pandas更深的内容。
# 导入库:
import numpy as np
import pandas as pd
# 制作DataFrame
np.random.seed(10)
period = pd.date_range('2017-1-1', periods=10000, freq='D')
df = pd.DataFrame(np.random.randn(10000, 4),
columns=['Data1', 'Data2', 'Data3', 'Data4'],
index = period)
print(df.head())
# Data1 Data2 Data3 Data4
# 2017-01-01 1.331587 0.715279 -1.545400 -0.008384
# 2017-01-02 0.621336 -0.720086 0.265512 0.108549
# 2017-01-03 0.004291 -0.174600 0.433026 1.203037
# 2017-01-04 -0.965066 1.028274 0.228630 0.445138
# 2017-01-05 -1.136602 0.135137 1.484537 -1.079805
# 1> Group操作
# ① 一重分组
df['G1'] = np.random.choice(['A','B','C','D'],10000) # 新加一列用作分组。
grouped = df.groupby('G1')
print(grouped.size()) # 查看分组情况。
# G1
# A 2484
# B 2491
# C 2502
# D 2523
# dtype: int64
grouped.sum() # 分组求和
grouped.max() # 寻找分组最大的
grouped.mean() # 分组求平均
grouped.describe() # 分组统计量
np.transpose(grouped.describe()) # 转置
print(grouped.get_group('A').head()) # 挑出分组为A的DataFrame。
# ②双重分组
# 再建立一个分组
df['G2'] = np.random.choice(['S','Y'],10000)
grouped = df.groupby(['G1','G2']) # 哪个分组在前面就先按哪个分组分类。
# 聚合运算。按G1、G2分组后,分别求Data1和Data2的平均值和最大值。
print(grouped.agg({'Data1':np.mean, 'Data2':np.max}))
# 2> 合并操作
# 建立DataFrame
df1 = pd.DataFrame(['1','2','3','4'],
index=['a','b','c','g'],
columns=['A'])
df2 = pd.DataFrame(['5','6','7','8'],
index=['a','b','e','f'],
columns=['B'])
# ① 用concat合并DataFrame
df = pd.concat((df1,df2),axis=1,ignore_index=False) # 横向合并
print(df)
# A B
# a 1 5
# b 2 6
# c 3 NaN
# g 4 NaN
# e NaN 7
# f NaN 8
# 自动按索引合并,为空不会报错。
# ② DataFrame内置合并方法
df = pd.DataFrame({'A': df1['A'], 'B': df2['B']})
# ③ Join操作(有条件的合并)
df1.join(df2,how='left') # 按df1的索引合并,left是默认值,还可以写right,inner,outer。
# ④ Merge操作
df1 = pd.DataFrame(['1','2','3','4'],
index=['a','b','c','d'],
columns=['A',])
df2 = pd.DataFrame(['5','6','7','8'],
index=['a','b','c','d'],
columns=['B',])
c = pd.Series(['10','11','12','13'],
index=['a','b','c','d'])
# df1和df2都新增一列。
df1['C'] = c
df2['C'] = c
# 合并
print(pd.merge(df1,df2,on='C')) # 该函数默认将一样的列合并。on的默认值在这里就是C.
# A C B
# 0 1 10 5
# 1 2 11 6
# 2 3 12 7
# 3 4 13 8
# 索引会重置。
# 注意,慎用这里的on参数.当C内的数据有重复时,用on参数达不到预想的合并效果。
# 转而用下面的方法合并。(根据索引合并)
print(pd.merge(df1,
df2,
left_index=True,
right_index=True,
suffixes=['_df1','_df2']))
# A C_df1 B C_df2
# a 1 10 5 10
# b 2 11 6 11
# c 3 12 7 12
# d 4 13 8 13
# 其中还有how参数,inner和outer。当df1和df2不同长度时,读者可以自己尝试下效果。
# 3> 层次化索引
np.random.seed(10)
df = pd.Series(np.random.randn(5),
index=[['a', 'a', 'b','b', 'b'],
[1,2,1,2,3]])
print(df)
# a 1 1.331587
# 2 0.715279
# b 1 -1.545400
# 2 -0.008384
# 3 0.621336
# a,b为level 0,123为level 1。
# dtype: float64
# 用unstack()重新排列
df.unstack()
df.unstack().T # 转置
df.unstack().stack() # 逆运算
print(df.sum(level=0)) # 按level0聚合
# a 2.046865
# b -0.932448
# dtype: float64
print(df.sum(level=1)) # 按level1聚合
# 1 -0.213814
# 2 0.706895
# 3 0.621336
# dtype: float64