pandas交叉与透视表
一、交叉表:
交叉表是将DataFrame
中两列的数据进行交叉,其中一列的值作为行索引,另一列的值作为列索引,然后求交叉数据出现的次数。也可以通过指定aggfunc
和values
,来改变两列交叉后的结果。这里我们先创建一个简单的DataFrame
测试数据:
df = pd.DataFrame({'A': [1, 2, 2, 2, 2],
'B': [3, 3, 4, 4, 4],
'C': [1, 1, np.nan, 1, 1]})
df.head()
输出结果如下:
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
1. 默认使用:
我们求A
列和B
列交叉后出现的次数,那么可以通过以下代码实现:
pd.crosstab(df['A'], df['B'])
输出结果如下:
B 3 4
A
1 1 0
2 1 3
可以看到,A
列为1,B
列为3的数据,总共出现了1次,而A
列为2,B
列为4的数据,总共出现了3次。
2. 使用聚合函数:
我们也可以使用聚合函数,来修改聚合后的计算结果,这里我们计算C
这一列的总和,那么代码如下:
pd.crosstab(df['A'], df['B'], values=df['C'], aggfunc=np.sum)
输出结果如下:
B 3 4
A
1 1.0 NaN
2 1.0 2.0
上述代码中,在A=1
,B=3
的前提下,C
列的所有值的总和为1。而在A=1
,B=4
的前提下,C
列所有值的总和为2。
二、透视表:
透视表有点类似于groupby
,先通过index
参数指定分组的列,然后再通过values
参数指定聚合的列,再通过aggfunc
参数指定聚合的函数。我们使用以下测试数据集:
df = pd.DataFrame({"A": ["foo", "foo", "foo", "foo", "foo",
"bar", "bar", "bar", "bar"],
"B": ["one", "one", "one", "two", "two",
"one", "one", "two", "two"],
"C": ["small", "large", "large", "small",
"small", "large", "small", "small",
"large"],
"D": [1, 2, 2, 3, 3, 4, 5, 6, 7],
"E": [2, 4, 5, 5, 6, 6, 8, 9, 9]})
df
输出结果如下:
A B C D E
0 foo one small 1 2
1 foo one large 2 4
2 foo one large 2 5
3 foo two small 3 5
4 foo two small 3 6
5 bar one large 4 6
6 bar one small 5 8
7 bar two small 6 9
8 bar two large 7 9
1. 默认使用:
df.pivot_table(index='A')
输出结果如下:
D E
A
bar 5.5 8.0
foo 2.2 4.4
默认是根据index
的列进行分组,然后求类型为数值型的列的平均值。
2. 根据A
列进行分组,统计每个值出现的次数。示例代码如下:
df.pivot_table(index='A', aggfunc=np.count_nonzero)
输出结果如下:
B C D E
A
bar 4 4 4 4
foo 5 5 5 5
3. 根据A
列进行分组,统计D
列的值的总和。示例代码如下:
df.pivot_table(index='A', values=['D'], aggfunc=np.sum)
输出结果如下:
D
A
bar 22
foo 11
4. 根据A
列进行分组,统计D
列的值的总和,并且根据B
列进行区分。示例代码如下:
df.pivot_table(index='A', values=['D'], columns=['B'], aggfunc=np.sum)
输出结果如下:
D
B one two
A
bar 9 13
foo 5 6