用列表中的值替换 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
您还可以执行 groupby
和 transform
,使用 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
我有一个由 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
您还可以执行 groupby
和 transform
,使用 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