Pandas:如果组在另一列中至少有一个共同点,则将组的值重新分配给一列中的相同值

l7mqbcuq  于 2023-09-29  发布在  其他
关注(0)|答案(2)|浏览(107)

我有以下dataframe:

df = pd.DataFrame({"zip":['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A','C', 'C', 'C','C', 'C', 'C'],
                   "zip_splitted":['A_1', 'A_1', 'A_1','A_1', 'A_1', 'A_1', 
                                   'A_2', 'A_2', 'A_2','A_2', 'A_2', 'A_2', 
                                   'C_1', 'C_1', 'C_1', 'C_1', 'C_1', 'C_1'], 
                   "cluster":['111', '111', '111', '112', '112', '112', 
                              '113', '113', '113', '114', '114', '114', 
                              '115', '115', '115', '116', '116', '116'],                  
                   "cluster2":['991', '991', '994', '991', '882', '991', 
                               '993', '991', '994', '992', '991', '991',
                              '889', '889', '992', '998', '997', '999']
                  })

| zip| zip_splitted|集群|cluster2|
| --|--|--|--|
| 一|A_1| 111 | 991 |
| 一|A_1| 111 | 991 |
| 一|A_1| 111 | 994 |
| 一|A_1| 112 | 991 |
| 一|A_1| 112 | 882 |
| 一|A_1| 112 | 991 |
| 一|A_2| 113 | 993 |
| 一|A_2| 113 | 991 |
| 一|A_2| 113 | 994 |
| 一|A_2| 114 | 992 |
| 一|A_2| 114 | 991 |
| 一|A_2| 114 | 991 |
| C| C_1| 115 | 889 |
| C| C_1| 115 | 889 |
| C| C_1| 115 | 992 |
| C| C_1| 116 | 998 |
| C| C_1| 116 | 997 |
| C| C_1| 116 | 999 |
主要目标是重新分配“cluster”中的值,以便如果“cluster”中的值组在“cluster 2”值中至少有一个相同的值,则它们应该与相同的群集ID组合。
对于当前情况,输出应如下(群集111、112、113、114、115、116-在群集2中至少有一个公共值,将它们重新分配给111、116 -保持相同):
| zip| zip_splitted|集群|cluster2|集群新闻|
| --|--|--|--|--|
| 一|A_1| 111 | 991 | 111 |
| 一|A_1| 111 | 991 | 111 |
| 一|A_1| 111 | 994 | 111 |
| 一|A_1| 112 | 991 | 111 |
| 一|A_1| 112 | 882 | 111 |
| 一|A_1| 112 | 991 | 111 |
| 一|A_2| 113 | 993 | 111 |
| 一|A_2| 113 | 991 | 111 |
| 一|A_2| 113 | 994 | 111 |
| 一|A_2| 114 | 992 | 111 |
| 一|A_2| 114 | 991 | 111 |
| 一|A_2| 114 | 991 | 111 |
| C| C_1| 115 | 889 | 111 |
| C| C_1| 115 | 889 | 111 |
| C| C_1| 115 | 992 | 111 |
| C| C_1| 116 | 998 | 116 |
| C| C_1| 116 | 997 | 116 |
| C| C_1| 116 | 999 | 116 |
目前被groupbys卡住了,试图创建一个Map列表,但不确定这是一个正确的方法。
感谢任何帮助。

gopyfrb3

gopyfrb31#

试试这个:

import networkx as nx

L = df.groupby('cluster')['cluster2'].agg(list)
G=nx.Graph()
for l in L:
    nx.add_path(G, l)
df = (df.assign(cluster_new = df.groupby(df['cluster2'].map(
    {v2:k for k,v in enumerate(list(nx.connected_components(G))) for v2 in v}
    ))['cluster'].transform('first')))

输出量:

zip zip_splitted cluster cluster2 cluster_new
0    A          A_1     111      991         111
1    A          A_1     111      991         111
2    A          A_1     111      994         111
3    A          A_1     112      991         111
4    A          A_1     112      882         111
5    A          A_1     112      991         111
6    A          A_2     113      993         111
7    A          A_2     113      991         111
8    A          A_2     113      994         111
9    A          A_2     114      992         111
10   A          A_2     114      991         111
11   A          A_2     114      991         111
12   C          C_1     115      889         111
13   C          C_1     115      889         111
14   C          C_1     115      992         111
15   C          C_1     116      998         116
16   C          C_1     116      997         116
17   C          C_1     116      999         116
jw5wzhpr

jw5wzhpr2#

用pandas iterrows()创建的解决方案也在工作,但图形方法看起来更好,可能更快。

new_cluster_ids = {}

# Iterate over each row in the dataframe
for index, row in df.iterrows():
    cluster = row['cluster']
    cluster2 = row['cluster2']

    # Check if the cluster already has a new ID assigned
    if cluster in new_cluster_ids:
        new_cluster_id = new_cluster_ids[cluster]
    else:
        new_cluster_id = cluster
    
    # Find other rows with the same cluster2 value
    same_cluster2_rows = df[df['cluster2'] == cluster2]
    
    # Update the new cluster ID for all rows with the same cluster2 value
    for _, same_cluster2_row in same_cluster2_rows.iterrows():
        new_cluster_ids[same_cluster2_row['cluster']] = new_cluster_id
    
df['cluster_new'] = df['cluster'].map(new_cluster_ids)

print(df)

相关问题