我有两个类别 A 和 B ,可以采用列表定义的 5种不同状态(值,名称或类别) ABCDE 即可。计算每个状态的出现并将其存储在数据帧中相当容易。但是,我还希望结果数据框中包含未在类别 A 或 B 中出现的可能值的零。
首先,这是一个与描述匹配的数据框:
在[1]中:
import pandas as pd
possibleValues = list('abcde')
df = pd.DataFrame({'Category A':list('abbc'), 'Category B':list('abcc')})
print(df)
出[1]:
Category A Category B
0 a a
1 b b
2 b c
3 c c
我尝试了df.groupby(...).size()
和.count()
的不同方法,并列出了可能的值列表和列表中类别的名称,但没有成功。
这是所需的输出:
Category A Category B
a 1 1
b 2 1
c 1 2
d 0 0
e 0 0
为了更进一步,我还希望在所有类别中包含一个列,其中包含每个可能状态的总计:
Category A Category B Total
a 1 1 2
b 2 1 3
c 1 2 3
d 0 0 0
e 0 0 0
SO有很多相关的问题和答案,但据我所知,没有任何一个能够解决这一特定问题。谢谢你的任何建议!
P.S
我想使解决方案可以根据类别数量,可能的值和行数进行调整。
答案 0 :(得分:3)
需要apply
+ value_counts
+ reindex
+ sum
:
cols = ['Category A','Category B']
df1 = df[cols].apply(pd.value_counts).reindex(possibleValues, fill_value=0)
df1['total'] = df1.sum(axis=1)
print (df1)
Category A Category B total
a 1 1 2
b 2 1 3
c 1 2 3
d 0 0 0
e 0 0 0
另一种解决方案是将列转换为categorical,然后在不0
的情况下添加reindex
个值:
cols = ['Category A','Category B']
df1 = df[cols].apply(lambda x: pd.Series.value_counts(x.astype('category',
categories=possibleValues)))
df1['total'] = df1.sum(axis=1)
print (df1)
Category A Category B total
a 1 1 2
b 2 1 3
c 1 2 3
d 0 0 0
e 0 0 0