将DataFrame中一行的值复制到所有相关行
我有一个叫做 data 的数据框,它可能有多行数据。这个数据框里有一列叫做 a1,长度是10位数字。如果 a1 的前7位数字相同,那么这些行就属于同一组。通过行内的一些信息和另一个数据框中的一些数据,可以为这些相关的行计算一个标记(Flag)。
这个标记的值只能是0或1。
当某一组相关行的标记值计算为1时,其他所有相关行的标记值都应该变为0。
最后,这部分我有点困惑,一旦完成了前面的步骤,我需要把标记值为1的那一行的 a1 值复制到所有其他相关行的 a1 值上。也就是说,标记值为0的行应该更新,使得它们的 a1 值和标记值为1的那一行的 a1 值相同。
举个例子 -
初始的 'data' 数据框(为了简单起见,我这里只有2行数据) -
a0 a1 a2 .......
88554 6667778892 12 .......
88554 6667778895 2 .......
经过标记计算后的 'data' -
a0 a1 a2 ....... flag
88554 6667778892 12 ....... 1
88554 6667778895 2 ....... 0
以上的步骤通过下面的代码看起来是可以正常工作的 -
data['flag'] = data.sort_values(relevant_columns, ascending = [True, True, False, False, False, False]).groupby(["a1_f7"])["Rank"].cumsum()
data['flag'] = np.where(data['flag'] == 1, 1, 0)
现在,最后一步是需要把标记为1的那一行的 a1 值复制到所有其他行的 a1 值上,但这一步没有正确执行 -
a0 a1 a2 ....... flag
88554 6667778892 12 ....... 1
88554
6667778892
2 ....... 0
这是我尝试过的 -
row_with_flag_record = data.loc[data['flag'] == 1]
data['a1'] = row_with_flag_record['a1'].astype(str)
但我得到的是一个空值,而不是第二行的 6667778892 -
a0 a1 a2 ....... flag
88554 6667778892 12 ....... 1
88554
NaN
2 ....... 0
1 个回答
你看到NaN值是因为这个筛选条件 row_with_flag_record
跳过了所有 flag == 0
的行。
我能想到的最简单的方法——不过可能还有更简单的方法!——是这样的。你需要一种方式,把 a1
的前缀和有标记的 a1
值对应起来。所以,你可以用一个字典来实现:
g2a = dict((str(k)[:7], k) for k in df.loc[df.flag == 1].a1)
这样就简单多了:
df.a1 = df.a1.apply(lambda s: g2a[str(s)[:7]])
另外,@Scott-Boston 提供的方法也可以用:
df['a1'] = df.groupby(df['a1'].astype(str).str[:7])['a1'].transform('first')
但这个方法要求 df.a1
和标记值要按一定顺序排列。所以,你得到:
df.a1 = df.sort_values("flag", ascending=False).groupby(df.a1.astype(str).str[:7])['a1'].transform('first')