https://blog.csdn.net/weixin_44507435/article/details/104914276
# 透视表:pivot_table
# pd.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All')
date = ['2017-5-1','2017-5-2','2017-5-3']*3
rng = pd.to_datetime(date)
df = pd.DataFrame({'date':rng,
'key':list('abcdabcda'),
'values':np.random.rand(9)*10})
print(df)
print('-----')
print(pd.pivot_table(df, values = 'values', index = 'date', columns = 'key', aggfunc=np.sum)) # 也可以写 aggfunc='sum'
print('-----')
# data:DataFrame对象
# values:要聚合的列或列的列表
# index:数据透视表的index,从原数据的列中筛选,即分类聚合的标准
# columns:数据透视表的columns,从原数据的列中筛选
# aggfunc:用于聚合的函数,默认为numpy.mean,支持numpy计算方法
print(pd.pivot_table(df, values = 'values', index = ['date','key'], aggfunc=len))
print('-----')
# 这里就分别以date、key共同做数据透视,值为values:统计不同(date,key)情况下values的平均值
# aggfunc=len(或者count):计数
date key values
0 2017-05-01 a 5.886424
1 2017-05-02 b 9.906472
2 2017-05-03 c 8.617297
3 2017-05-01 d 8.972318
4 2017-05-02 a 7.990905
5 2017-05-03 b 8.131856
6 2017-05-01 c 2.823731
7 2017-05-02 d 2.394605
8 2017-05-03 a 0.667917
-----
key a b c d
date
2017-05-01 5.886424 NaN 2.823731 8.972318
2017-05-02 7.990905 9.906472 NaN 2.394605
2017-05-03 0.667917 8.131856 8.617297 NaN
-----
date key
2017-05-01 a 1.0
c 1.0
d 1.0
2017-05-02 a 1.0
b 1.0
d 1.0
2017-05-03 a 1.0
b 1.0
c 1.0
Name: values, dtype: float64
-----
# 交叉表:crosstab
# 默认情况下,crosstab计算因子的频率表,比如用于str的数据透视分析
# pd.crosstab(index, columns, values=None, rownames=None, colnames=None, aggfunc=None, margins=False, dropna=True, normalize=False)
df = pd.DataFrame({'A': [1, 2, 2, 2, 2],
'B': [3, 3, 4, 4, 4],
'C': [1, 1, np.nan, 1, 1]})
print(df)
print('-----')
print(pd.crosstab(df['A'],df['B']))
print('-----')
# 如果crosstab只接收两个Series,它将提供一个频率表。
# 用A的唯一值,统计B唯一值的出现次数
print(pd.crosstab(df['A'],df['B'],normalize=True))
print('-----')
# normalize:默认False,将所有值除以值的总和进行归一化 → 为True时候显示百分比
print(pd.crosstab(df['A'],df['B'],values=df['C'],aggfunc=np.sum))
print('-----')
# values:可选,根据因子聚合的值数组
# aggfunc:可选,如果未传递values数组,则计算频率表,如果传递数组,则按照指定计算
# 这里相当于以A和B界定分组,计算出每组中第三个系列C的值
print(pd.crosstab(df['A'],df['B'],values=df['C'],aggfunc=np.sum, margins=True))
print('-----')
# margins:布尔值,默认值False,添加行/列边距(小计)
A B C
0 1 3 1.0
1 2 3 1.0
2 2 4 NaN
3 2 4 1.0
4 2 4 1.0
-----
B 3 4
A
1 1 0
2 1 3
-----
B 3 4
A
1 0.2 0.0
2 0.2 0.6
-----
B 3 4
A
1 1.0 NaN
2 1.0 2.0
-----
B 3 4 All
A
1 1.0 NaN 1.0
2 1.0 2.0 3.0
All 2.0 2.0 4.0
-----
作业一:按要求创建Dataframe df,并通过数据透视表或交叉表得到以下结果① 以A列聚合,求出C,D的平均值② 以A,B列聚合,求出D,E的均值、求和③ 以B聚合,计算A列的元素频率
#作业十二
df15 = pd.DataFrame({'A':['one','two','three','one','two','three','one','two']
,'B':['h','h','h','h','f','f','f','f']
,'C':np.arange(10,25,2)
,'D':np.random.rand(8)*2-1
,'E':np.random.rand(8)
})
print('创建的df:\n',df15)
print('------------------')
print('以A列聚合,求C、D的均值:\n',pd.pivot_table(df15,values = ['C','D'],index = 'A',aggfunc = np.mean))
print('------------------')
print('以A、B列聚合,求C、D列的均值、求和:\n',pd.pivot_table(df15,values = ['C','D'],index = ['A','B'],aggfunc = [np.mean,np.sum]))
print('------------------')
print('以B聚合,计算A列元素的频率:\n',pd.crosstab(df15['B'],df15['A'],normalize = True,margins = True))
创建的df:
A B C D E
0 one h 10 -0.313872 0.300225
1 two h 12 -0.672241 0.337176
2 three h 14 0.883489 0.888377
3 one h 16 -0.028301 0.393548
4 two f 18 0.624565 0.952166
5 three f 20 0.933810 0.737138
6 one f 22 -0.127910 0.027119
7 two f 24 -0.133072 0.450813
------------------
以A列聚合,求C、D的均值:
C D
A
one 16 -0.156694
three 17 0.908649
two 18 -0.060249
------------------
以A、B列聚合,求C、D列的均值、求和:
mean sum
C D C D
A B
one f 22 -0.127910 22 -0.127910
h 13 -0.171087 26 -0.342174
three f 20 0.933810 20 0.933810
h 14 0.883489 14 0.883489
two f 21 0.245747 42 0.491493
h 12 -0.672241 12 -0.672241
------------------
以B聚合,计算A列元素的频率:
A one three two All
B
f 0.125 0.125 0.250 0.5
h 0.250 0.125 0.125 0.5
All 0.375 0.250 0.375 1.0