我有这样的代码
frame[frame['value_text'].str.match('Type 2') | frame['value_text'].str.match('Type II diabetes')].groupby(['value_text','gender'])['value_text'].count()
返回类似
的系列value_text gender count
type 2 M 4
type 2 without... M 4
F 3
我想要的是
value_text gender count
type 2 M 4
F 0
type 2 without... M 4
F 3
我希望包括所有性别的计数,即使数据框中没有记录。我怎么能这样做?
答案 0 :(得分:1)
请记住,每当您想强制使用特定列表来索引/整形数据时。 Pivot ,交叉表,堆栈, unstack 不可靠,因为它们高度依赖于输入数据。例如,如果“M”从未显示在任何输入行中,则无论您如何转动/取消堆叠结果,都不会看到“M”。这种问题是 reindex()闪耀的地方。
假设您预先处理的相框保存为 df :
mdx1 = pd.MultiIndex.from_product([df.index.levels[0], ['M', 'F']])
df.reindex(mdx1).fillna(0, downcast='infer')
另一方面,如果您只想在所有级别0中显示所有可能的级别1值,请执行以下操作:
mdx1 = pd.MultiIndex.from_product(df.index.levels)
df.reindex(mdx1).fillna(0, downcast='infer')
这可以很容易地扩展到具有2级以上索引的数据帧。
更新:使用分类数据类型可能会修复类似枢轴的函数所具有的问题。
答案 1 :(得分:1)
Categorical Data已在pandas
中专门用于此目的。
实际上,使用分类数据的groupby
操作会自动计算笛卡尔积。
与其他功能方法相比,您应该会看到更多优势:更低的内存使用率和数据验证。
import pandas as pd
df = pd.DataFrame({'value_text': ['type2', 'type2 without', 'type2'],
'gender': ['M', 'F', 'M'],
'value': [1, 2, 3]})
df['gender'] = df['gender'].astype('category')
res = df.groupby(['value_text', 'gender']).count()\
.fillna(0).astype(int)\
.reset_index()
print(res)
value_text gender value
0 type2 F 0
1 type2 M 2
2 type2 without F 1
3 type2 without M 0
答案 2 :(得分:0)
尝试将.unstack().fillna(0).stack()
附加到当前行,如下所示:
frame[frame['value_text'].str.match('Type 2') |
frame['value_text'].str.match('Type II diabetes')]\
.groupby(['value_text','gender'])['value_text'].count()\
.unstack().fillna(0).stack()
答案 3 :(得分:0)
最简单的方法是pd.crosstab
然后stack
:
# save your filtered dataframe as an intermediate result, for convenience
type2 = frame[frame.value_text.str.match('Type 2|Type II diabetes')]
pd.crosstab(type2.value_text, type2.gender).stack()