如何在pandas中做groupby()和value_counts()之类的操作?
How to do some operations like groupby() and value_counts() in pandas?
这是一个 pandas 数据框,定义如下:
df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo', 'foo'],
'B' : ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three', 'two'],
'C' : [0, 1, 0, 1, 1, 2, 0, 2, 1]})
>>> df
A B C
0 foo one 0
1 bar one 1
2 foo two 0
3 bar three 1
4 foo two 1
5 bar two 2
6 foo one 0
7 foo three 2
8 foo two 1
我想做两个手术
首先,按 A
和 B
列对 Dataframe 进行分组。因此,在这种情况下获得 6 个组。这个操作类似于pandas.
中的groupby()函数
然后,对于每个组,对列 C
进行计数操作,因为在这种情况下它可以是三个不同的值(0、1 和 2)。这个操作类似于pandas.
中的value_counts()函数
最后,我想要一个像这样的新 Dataframe。
A B C_value0 C_value1 C_value2
0 foo one 2 0 0
1 foo two 1 2 0
2 foo three 0 0 1
3 bar one 0 1 0
4 bar two 0 0 1
5 bar three 0 1 0
有人能告诉我如何实现吗?谢谢!
您可以使用 groupby
with aggregating size
, then replace NaN
to 0
by fillna
, convert to int
by astype
, add_prefix
, reset_index
and last rename_axis
(pandas
0.18.0
中的新功能):
print (df.groupby(['A','B', 'C'])['C'].size()
.unstack()
.fillna(0)
.astype(int)
.add_prefix('C_value')
.reset_index()
.rename_axis(None, axis=1))
A B C_value0 C_value1 C_value2
0 bar one 0 1 0
1 bar three 0 1 0
2 bar two 0 0 1
3 foo one 2 0 0
4 foo three 0 0 1
5 foo two 1 2 0
crosstab
的另一个解决方案:
print (pd.crosstab([df.A, df.B], df.C)
.add_prefix('C_value')
.reset_index()
.rename_axis(None, axis=1))
A B C_value0 C_value1 C_value2
0 bar one 0 1 0
1 bar three 0 1 0
2 bar two 0 0 1
3 foo one 2 0 0
4 foo three 0 0 1
5 foo two 1 2 0
这是一个 pandas 数据框,定义如下:
df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo', 'foo'],
'B' : ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three', 'two'],
'C' : [0, 1, 0, 1, 1, 2, 0, 2, 1]})
>>> df
A B C
0 foo one 0
1 bar one 1
2 foo two 0
3 bar three 1
4 foo two 1
5 bar two 2
6 foo one 0
7 foo three 2
8 foo two 1
我想做两个手术
首先,按 A
和 B
列对 Dataframe 进行分组。因此,在这种情况下获得 6 个组。这个操作类似于pandas.
然后,对于每个组,对列 C
进行计数操作,因为在这种情况下它可以是三个不同的值(0、1 和 2)。这个操作类似于pandas.
最后,我想要一个像这样的新 Dataframe。
A B C_value0 C_value1 C_value2
0 foo one 2 0 0
1 foo two 1 2 0
2 foo three 0 0 1
3 bar one 0 1 0
4 bar two 0 0 1
5 bar three 0 1 0
有人能告诉我如何实现吗?谢谢!
您可以使用 groupby
with aggregating size
, then replace NaN
to 0
by fillna
, convert to int
by astype
, add_prefix
, reset_index
and last rename_axis
(pandas
0.18.0
中的新功能):
print (df.groupby(['A','B', 'C'])['C'].size()
.unstack()
.fillna(0)
.astype(int)
.add_prefix('C_value')
.reset_index()
.rename_axis(None, axis=1))
A B C_value0 C_value1 C_value2
0 bar one 0 1 0
1 bar three 0 1 0
2 bar two 0 0 1
3 foo one 2 0 0
4 foo three 0 0 1
5 foo two 1 2 0
crosstab
的另一个解决方案:
print (pd.crosstab([df.A, df.B], df.C)
.add_prefix('C_value')
.reset_index()
.rename_axis(None, axis=1))
A B C_value0 C_value1 C_value2
0 bar one 0 1 0
1 bar three 0 1 0
2 bar two 0 0 1
3 foo one 2 0 0
4 foo three 0 0 1
5 foo two 1 2 0