假设我有一个这样的数据框
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的新列,该列根据这些行是否相同为我评分。
例如
迭代这些行并获得新列Rate并将其添加到当前数据帧的最佳方法是什么? 我尝试了一些不同的尝试,但暂时无法获得任何可行的解决方案。
答案 0 :(得分:0)
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
答案 1 :(得分:0)
实际上,无需在组行上重复。
任务是应用一个计算每个组的费率的功能。
所需的第一个组件是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点)。