Pandas如何合并相似行的列值

4

我有一个包含重复行的数据框,其中有一个唯一列值。如果任何一行具有重复值组合,则需要将唯一值连接到每行的一个列中。

示例数据:

| program | subject | course | title |
|:------- |:------- |:------ |:----- |
|music    | eng     | 101    | 000   |
|music    | math    | 101    | 123   |
|music    | eng     | 102    | 000   |
|music    | math    | 101    | 456   |
|art      | span    | 201    | 123   |
|art      | hst     | 101    | 000   |
|art      | span    | 201    | 456   |
|art      | span    | 202    | 000   |

所需数据

| program | subject | course | title.   |
|:------- |:------- |:------ |:-----    |
|music    | eng     | 101    | 000      |
|music    | math    | 101    | 123-456  |
|music    | eng     | 102    | 000      |
|music    | math    | 101    | 456-123  |
|art      | span    | 201    | 123-456  |
|art      | hst     | 101    | 000      |
|art      | span    | 201    | 456-123  |
|art      | span    | 202    | 000      |

第二行和第四行以及第五行和第七行的前三列匹配。我想将标题连接起来,以便每一行包含匹配行的标题组合。

这假设只有2个重复项?如果有3个呢? - anky
现在,只有两个副本。 - JElwood
3个回答

2

尝试使用networkx进行实验,以匹配精确的预期输出,可能有点过于复杂:

import networkx as nx

u = df.assign(k=df.groupby(['program','subject','course']).ngroup())
G = nx.from_pandas_edgelist(u,'title','k',create_using=nx.DiGraph())
l =[f"{a}-{''.join(b.difference([a]))}".rstrip("-") 
 for a,b in zip(u['title'],u['k'].map(lambda x: nx.ancestors(G,x)))]
df['new_title'] = l

print(df)

  program subject course title new_title
0   music     eng    101   000       000
1   music    math    101   123   123-456
2   music     eng    102   000       000
3   music    math    101   456   456-123
4     art    span    201   123   123-456
5     art     hst    101   000       000
6     art    span    201   456   456-123
7     art    span    202   000       000

2

让我们尝试使用 groupby transform

df['title'] = df.groupby(
    ['program', 'subject', 'course'], as_index=False, sort=False
)['title'].transform('-'.join)
print(df)

输出:

  program subject  course    title
0   music     eng     101      000
1   music    math     101  123-456
2   music     eng     102      000
3   music    math     101  123-456
4     art    span     201  123-456
5     art     hst     101      000
6     art    span     201  123-456
7     art    span     202      000

就目前看来,这应该足够了。 - anky
1
谢谢。我不确定这个问题是否需要像你这样花费额外的计算时间来强制排序列表。由于主要请求似乎只是“将唯一值连接到每行的列中”,因此我不确定是否需要这样做。 - Henry Ecker
1
是的,我想只有两个重复项,我们可以接受它 :) 没必要把它搞得复杂化。 - anky

0
你可以合并两个数据框,然后删除重复的行。
frames = [df1, df2]
result = pd.concat(frames)

# dropping duplicate values
result.drop_duplicates(keep=False,inplace=True)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接