为了账号安全,请及时绑定邮箱和手机立即绑定

迭代分组行 Python pandas

迭代分组行 Python pandas

婷婷同学_ 2022-11-18 20:56:58
假设我有一个这样的数据框df_test = pd.DataFrame({"ID": [912665, 455378, 938724, 557830                         ],                    "NAME": ["Anna","Anna","Diana","Peter"                            ],                    "LAST_NAME": ["Johns","Johns","Scott","Scott"                            ],                    "ADDRESS": ["Address1","Address2","Address3","Address3"],                        "PHONE": ['0000000001','0000000001','0000000002','0000000002'                         ],                   "ngroup": [0, 0,1,1]}                      )df_test结果ngroup 列中有两组 - 0 和 1在每个组中,我想对一些列(如 NAME、LAST_NAME、ADDRESS)进行比较,并给出一个名为 Rate 的新列,它根据这些行是否相同给我一个分数。例如对于第 0 组,我们可以获得如下比率:5(因为姓名相同)+ 30(因为姓氏相同)+ 0(因为地址不同)+ 50(因为电话相同)= 85对于第 1 组:0 + 30 + 15 + 30 = 75迭代这些行并获取新列 Rate 并将其添加到当前数据帧的最佳方法是什么?我正在尝试一些不同的事情,但目前无法获得任何可行的解决方案。
查看完整描述

2 回答

?
30秒到达战场

TA贡献1828条经验 获得超6个赞

实际上,没有必要遍历组行。

任务是应用一个函数来计算每个组的比率。

需要的第一个组件是 lambda 函数,应用于组(Numpy一维数组)中的每一列,检查所有元素是否相同。实际上,它检查元素0是否等于从1开始的所有元素并返回1(作为True)或0作为(False)。

lambda v: (v[0] == v[1:]).all().astype(int)

那么概念就是:

  • grp.values- 将当前组转换为Numpy数组。

  • [:, 1:-1]- 删除第一个 ( ID ) 和最后一个 ( ngroup ) 列。

  • apply_along_axis(...)- 将上述功能应用于每个剩余的列。参数0是轴号(将函数应用于每个列切片)。结果是一个由 1 或 0 组成的向量。

  • ... * [5, 30, 15, 50]- 将上述向量乘以每列的权重,得到列评级。

  • np.sum(...)- 对它们求和,得到整体组率。

这样做的代码是:

def getRate(grp):

    return np.sum(np.apply_along_axis(lambda v: (v[0] == v[1:]).all().astype(int),

        0, grp.values[:, 1:-1]) * [5, 30, 15, 50])

然后将上述函数应用于每个组:


df_test.groupby('ngroup').apply(getRate)

结果是:


ngroup

0    85

1    95

dtype: int64

请注意,第1组的结果是0 * 5 + 1 * 30 + 1 * 15 + 1 * 50 = 95,而不是您帖子中的75,因为PHONE列的权重为50 (请参见示例的第 1 点)。


查看完整回答
反对 回复 2022-11-18
?
蓝山帝景

TA贡献1843条经验 获得超7个赞

IIUC,您可以创建一个包含列名称的速率字典,然后是stack您map的值,同时仅对重复值求和。


rates = {'NAME' : 5, 'LAST_NAME' : 30, 'ADDRESS' : 0 ,'PHONE' : 50 }


s = df.groupby('ngroup').agg(list).stack().explode().duplicated().to_frame()



s['vals'] = s.index.get_level_values(1).map(rates)



s[s[0].eq(True)].groupby(level=0).sum()


          0   vals

ngroup            

0       3.0   85.0

1       4.0  130.0


查看完整回答
反对 回复 2022-11-18
  • 2 回答
  • 0 关注
  • 105 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信