python/pandas-按类别转换的值_计数

python/pandas-按类别转换的值_计数,python,pandas,Python,Pandas,我有一张像这样的桌子: +------------+------------+------------+------------+ | Category_1 | Category_2 | Category_3 | Category_4 | +------------+------------+------------+------------+ | a | b | b | y | | a | a

我有一张像这样的桌子:

+------------+------------+------------+------------+
| 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          |
+------------+------------+------------+------------+
+---+------------+----+----+----+
|   |            | 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 |
+---+------------+----+----+----+
我希望有一个类似pivot_表的结果,每个类别的频率计数。大概是这样的:

+------------+------------+------------+------------+
| 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          |
+------------+------------+------------+------------+
+---+------------+----+----+----+
|   |            | 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 |
+---+------------+----+----+----+

我知道我可以通过拆分表,给列值赋值,然后重新连接来实现。有没有更简单、更“pythonic”的方法来实现这一点?我认为它可能是沿着枢轴与转换的路线进行的,但到目前为止的测试最糟糕。

因此我们需要
熔化
(或
堆叠
)您的原始数据帧,然后我们进行
pd.crosstab
,您也可以使用
pd.pivot\u表

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

因此,我们需要将原始数据帧
melt
(或
stack
),然后我们进行
pd.crosstab
,您也可以使用
pd.pivot\u 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

首先使用
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

首先使用
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

成功了!非常感谢。因此,如果我理解正确的话:设置索引(这样它就不会被困在堆栈中,)堆栈将列移动到行中,然后在两种列类型上进行交叉表(默认为计数)?@iamthestarlord是的,你知道了。非常感谢。成功了!非常感谢。因此,如果我理解正确的话:设置索引(这样它就不会被困在堆栈中,)堆栈将列移动到行中,然后在两种列类型上进行交叉表(默认为计数)?@iamthestarlord是的,你知道了。非常感谢。