用列表中的值替换 pandas 子集中的所有值

Replace all value in a pandas subset by values from a list

我有一个由 3 个不同组 A、B、C 组成的数据集:

df = pd.DataFrame([[1, "A", "A"], [2, "B", "B"], [3, "A", "A"], [4, "B", "B"], [5, "C", "C"], [6, "C", "C"],
               [7, "A", "A"], [8, "B", "B"], [9, "C", "C"]],
              columns=["Index", "Group", "Cluster"])

对于每个组,我确定一些集群,我想用集群的值替换集群列。 每个集群都有一个列表

listA = [0, 1, 1]
listB = [1, 0, 1]
listC = [0, 0, 1]

我想在最后有这样的东西:

Index Group Cluster
1 A 0
2 B 1
3 A 1
4 B 0
5 C 0
6 C 0
7 A 1
8 B 1
9 C 1

您可以 groupby.cumcount 然后 merge:

d = {"A":listA,"B":listB,"C":listC}
u = pd.Series(d).explode().to_frame("Cluster")

v = df.assign(k=df.groupby('Group').cumcount()).merge(
           u.assign(k=u.groupby(level=0).cumcount()).reset_index() ,
left_on=['Group','k'],right_on=['index','k'],suffixes=('','_y'))

v['Cluster'] = v['Cluster_y']
out = v.reindex(columns=df.columns)

print(out)

   Index Group Cluster
0      1     A       0
1      2     B       1
2      3     A       1
3      4     B       0
4      5     C       0
5      6     C       0
6      7     A       1
7      8     B       1
8      9     C       1

尝试使用 for 循环

for x, y in zip(list('ABC'), [listA,listB,listC]):
     df.loc[df.Group == x, 'Cluster'] = y
df
Out[395]: 
   Index Group Cluster
0      1     A       0
1      2     B       1
2      3     A       1
3      4     B       0
4      5     C       0
5      6     C       0
6      7     A       1
7      8     B       1
8      9     C       1

这可能有点天真,但假设组的大小与集群标签的大小相匹配,您可以排序、分配和求助:

df.sort_values(['Group', 'Index'], inplace=True)
df['Cluster'] = listA + listB + listC
df.sort_values('Index', inplace=True)

结果df

   Index Group  Cluster
0      1     A        0
1      2     B        1
2      3     A        1
3      4     B        0
4      5     C        0
5      6     C        0
6      7     A        1
7      8     B        1
8      9     C        1

您还可以执行 groupbytransform,使用 dict 将标签映射到集群(如 anky 在 中所做的):

d = {"A":listA, "B":listB, "C":listC}
df['Cluster'] = df.groupby('Group')['Cluster'].transform(lambda x : d[x.name])

结果:

   Index Group  Cluster
0      1     A        0
1      2     B        1
2      3     A        1
3      4     B        0
4      5     C        0
5      6     C        0
6      7     A        1
7      8     B        1
8      9     C        1