Python 如何将一个DataFrame列透视到一个真值表,其中的列基于另一个DataFrame?

Python 如何将一个DataFrame列透视到一个真值表,其中的列基于另一个DataFrame?,python,pandas,dataframe,group-by,pandas-groupby,Python,Pandas,Dataframe,Group By,Pandas Groupby,我有一个df,带有用户id和类别。我想将其转换为一个真值表,以确定该用户是否至少有一个该类别的条目。但是,最后的表格还应包括“df_列表”中出现的所有类别的列,这些列可能根本不会出现在df中 现在我用一个groupby+size创建真值表,然后检查是否缺少任何列,然后手动将这些列设置为False,但我想知道在最初的groupby步骤中是否有办法实现这一点 下面是一个例子: import pandas as pd df = pd.DataFrame({'user_id': [1,1,1,2,2],

我有一个
df
,带有
用户id
类别。我想将其转换为一个真值表,以确定该用户是否至少有一个该类别的条目。但是,最后的表格还应包括“df_列表”中出现的所有类别的列,这些列可能根本不会出现在
df

现在我用一个
groupby
+
size
创建真值表,然后检查是否缺少任何列,然后手动将这些列设置为
False
,但我想知道在最初的
groupby
步骤中是否有办法实现这一点

下面是一个例子:

import pandas as pd
df = pd.DataFrame({'user_id': [1,1,1,2,2],
                 'category': ['A', 'B', 'D', 'A', 'F']})
df_list = pd.DataFrame({'category': ['A', 'B', 'C', 'D', 'E', 'F']})

df_truth = df.groupby(['user_id', 'category']).size().unstack(fill_value=0).astype(bool)
#category     A      B      D      F
#user_id                            
#1         True   True   True  False
#2         True  False  False   True
然后,为了获得所需的输出,我执行以下操作:

missing_vals = df_list.category.unique()[~pd.Series(df_list.category.unique()).isin(df_truth.columns)]
for element in missing_vals:
    df_truth.loc[:,element] = False
#category     A      B      D      F      C      E
#user_id                                          
#1         True   True   True  False  False  False
#2         True  False  False   True  False  False

选项1
交叉表

我建议将该列转换为分类数据类型<代码>交叉表
/
透视
将处理其余部分

i = df.user_id
j = pd.Categorical(df.category, categories=df_list.category)

pd.crosstab(i, j).astype(bool)

col_0       A      B      C      D      E      F
user_id                                         
1        True   True  False   True  False  False
2        True  False  False  False  False   True 

选项2
unstack
+
reindex

要修复现有代码,可以使用
reindex
简化第二步:

(df.groupby(['user_id', 'category'])
   .size()
   .unstack(fill_value=0)
   .reindex(df_list.category, axis=1, fill_value=0)
   .astype(bool)
)

category     A      B      C      D      E      F
user_id                                          
1         True   True  False   True  False  False
2         True  False  False  False  False   True
@ALollz欢迎:)如果顺序很重要,您可以将
ordered=True
作为额外参数添加到
pd.category
,这在标签本身没有顺序(例如,一周中的几天)时非常有用。