如何在单个列上使用 groupby 并对 Pandas 中的多个列进行比较?
Posted
技术标签:
【中文标题】如何在单个列上使用 groupby 并对 Pandas 中的多个列进行比较?【英文标题】:How to use groupby on a single column and perform comparisons for multiple columns in Pandas? 【发布时间】:2019-05-11 15:51:41 【问题描述】:我有一个用户数据框,无论他们是否已注册,以及模型对他们是否已注册的预测。我想找到每个用户:TP(他们注册并且模型预测他们会这样做)、FP(他们没有注册但模型预测他们会这样做)、FN(他们注册但模型预测不会)和TN(他们没有注册,模型预测没有)。这里 1 表示他们注册,0 表示他们没有。我想对用户进行分组,然后使用其他两列进行比较。例如,我可能有如下内容:
Users | Signed_up | Prediction |
User1 1 0
User2 0 0
User1 1 1
User3 1 1
User2 0 1
User2 0 0
...
For TP, the resulting table might look something like:
Users | TP |
User1 1
User2 0
User3 1
For TN, the resulting table might look something like:
Users | TN |
User1 0
User2 1
User3 0
and so on for FP and FN.
我假设我在 Users
列上分组并使用 lambda 函数来比较 Sign_up
和 Prediction
列,但我不确定如何实际执行此操作。我将不胜感激!
【问题讨论】:
【参考方案1】:在groupby
和groupby
+ sum
之前进行比较
(df.assign(TP = df.Signed_up & df.Prediction,
TN = (df.Signed_up == 0) & (df.Prediction == 0),
FN = df.Signed_up & (df.Prediction == 0),
FP = (df.Signed_up == 0) & df.Prediction)
.groupby('Users')['TP', 'TN', 'FN', 'FP'].sum())
TP TN FN FP
Users
User1 1 0.0 1.0 0.0
User2 0 2.0 0.0 1.0
User3 1 0.0 0.0 0.0
受@BrianJoseph 的启发,您可以通过groupby
全部3 列,确定大小,然后将除用户之外的所有内容拆开:
df.groupby([*df]).size().unstack([1,2]).fillna(0)
Signed_up 1 0
Prediction 0 1 0 1
Users
User1 1.0 1.0 0.0 0.0
User2 0.0 0.0 2.0 1.0
User3 0.0 1.0 0.0 0.0
【讨论】:
为了完整起见,您应该继续添加FN = (df.Signed_up == 1) & (df.Prediction == 1), FP = (df.Signed_up == 0) & (df.Prediction == 1))
,这样您就可以处理 FP 和 FN。不过为此点赞!【参考方案2】:
请记住,pandas 可以使用函数结果进行分组。为了区分这 4 类结果,您只需要知道Signed_up
和Prediction
之间的关系。你可以这样分类:
grps = df.groupby(lambda index: (df.loc[index, 'Signed_up'], df.loc[index, 'Prediction']))
这只是为您提供 groupby 对象,您可以随意命名组,例如:
tp_df = grps.get_group((1,1))
【讨论】:
【参考方案3】:如果创建不同的 dfs,对于您帖子中看起来像是的每个模型预测,您可以使用布尔掩码和 &
位运算符来执行此操作。 &
表示必须同时满足两个条件才能返回值,所以:
df = pd.read_csv('./Desktop/models.csv')
TP = df.loc[(df['Signed_up'] == 1) & (df['Prediction'] == 1)]
TN = df.loc[(df['Signed_up'] == 0) & (df['Prediction'] == 0)]
FN = df.loc[(df['Signed_up'] == 1) & (df['Prediction'] == 0)]
FP = df.loc[(df['Signed_up'] == 0) & (df['Prediction'] == 1)]
输出:
>>> TP
Users Signed_up Prediction
2 User1 1 1
3 User3 1 1
>>> TN = df.loc[(df['Signed_up'] == 0) & (df['Prediction'] == 0)]
>>> TN
Users Signed_up Prediction
1 User2 0 0
5 User2 0 0
>>> FN = df.loc[(df['Signed_up'] == 1) & (df['Prediction'] == 0)]
>>> FN
Users Signed_up Prediction
0 User1 1 0
>>> FP = df.loc[(df['Signed_up'] == 0) & (df['Prediction'] == 1)]
>>> FP
Users Signed_up Prediction
4 User2 0 1
【讨论】:
以上是关于如何在单个列上使用 groupby 并对 Pandas 中的多个列进行比较?的主要内容,如果未能解决你的问题,请参考以下文章
从 Spark DataSet 中的单个列派生多个列并在新列上分组 [重复]