python / pandas - 按类别转换value_counts

时间:2018-03-30 14:50:19

标签: python pandas

我有一张看起来像这样的表:

+------------+------------+------------+------------+
| Category_1 | Category_2 | Category_3 | Category_4 |
+------------+------------+------------+------------+
| a          | b          | b          | y          |
| a          | a          | c          | y          |
| c          | c          | c          | n          |
| b          | b          | c          | n          |
| a          | a          | a          | y          |
+------------+------------+------------+------------+

我希望得到一个类似于pivot_table的结果,以及每个类别的频率计数。像这样:

+---+------------+----+----+----+
|   |            | a  | b  | c  |
+---+------------+----+----+----+
|   | Category_1 | 12 | 10 | 40 |
| y | Category_2 | 15 | 48 | 26 |
|   | Category_3 | 10 |  2 |  4 |
|   | Category_1 |  5 |  6 |  4 |
| n | Category_2 |  9 |  5 |  2 |
|   | Category_3 |  8 |  4 |  3 |
+---+------------+----+----+----+

我知道我可以通过拆分表,将value_counts分配给列值然后重新加入来将其拉出来。有没有更简单,更多' pythonic'拉这个的方式?我认为它可能沿着一个与变换配对的枢轴线,但到目前为止的测试充其量只是丑陋。

2 个答案:

答案 0 :(得分:2)

因此我们需要melt(或stack)原始数据框,然后我们执行pd.crosstab,您也可以使用pd.pivot_table

s=df.set_index('Category_4').stack().reset_index().rename(columns={0:'value'})
pd.crosstab([s.Category_4,s.level_1],s['value'])
Out[532]: 
value                  a  b  c
Category_4 level_1            
n          Category_1  0  1  1
           Category_2  0  1  1
           Category_3  0  0  2
y          Category_1  3  0  0
           Category_2  2  1  0
           Category_3  1  1  1

答案 1 :(得分:1)

首先使用get_dummies,然后对索引级别进行求和

d = pd.get_dummies(df.set_index('Category_4'))
d.columns = d.columns.str.rsplit('_', 1, True)
d = d.stack(0)

# This shouldn't be necessary but is because the
# index gets bugged and I'm "resetting" it
d.index = pd.MultiIndex.from_tuples(d.index.values)

d.sum(level=[0, 1])

              a  b  c
y Category_1  3  0  0
  Category_2  2  1  0
  Category_3  1  1  1
n Category_1  0  1  1
  Category_2  0  1  1
  Category_3  0  0  2