【PY从0到1】 一文掌握Pandas量化进阶

# 一文掌握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