使用pandas合并分组

4

想象一下由pandas数据帧组成的:

df = pd.DataFrame({
    'id': range(1, 10),
    'mfr': ('a', 'b', 'a', 'c', 'd', 'e', 'd', 'd', 'f'),
    'vmn': ('A', 'A', 'B', 'C', 'D', 'E', 'F', 'F', 'D')
})

以下是给出的表格

   id mfr vmn
0   1   a   A
1   2   b   A
2   3   a   B
3   4   c   C
4   5   d   D
5   6   e   E
6   7   d   F
7   8   d   F
8   9   f   D

我希望通过按mfr和/或vmn进行分组来确定哪些id彼此属于。我可以轻松地使用另一个来分配组ID。

df['groupby_mfr'] = df.groupby('mfr').grouper.group_info[0]
df['groupby_vmn'] = df.groupby('vmn').grouper.group_info[0]

以下是相关内容:

这将给出以下结果

   id mfr vmn  groupby_mfr  groupby_vmn
0   1   a   A            0            0
1   2   b   A            1            0
2   3   a   B            0            1
3   4   c   C            2            2
4   5   d   D            3            3
5   6   e   E            4            4
6   7   d   F            3            5
7   8   d   F            3            5
8   9   f   D            5            3

现在我想将它们组合成一个新的组ID,以便生成以下数据框:
   id mfr vmn  groupby_mfr  groupby_vmn  combined_group
0   1   a   A            0            0               0
1   2   b   A            1            0               0
2   3   a   B            0            1               0
3   4   c   C            2            2               1
4   5   d   D            3            3               2
5   6   e   E            4            4               3
6   7   d   F            3            5               2
7   8   d   F            3            5               2
8   9   f   D            5            3               2

前两行相同是因为vmn相等。第三行也属于同一组,因为对于vmn,第三行和第一行相同。以此类推... 另请注意,这将在多个列上运行,有许多行,因此性能也非常重要。

3
不清楚combined_group是如何计算的,请您详细说明一下。 - Zero
1
似乎需要图形。我认为这里需要使用 networkx 库。 - jezrael
对于两列,您可以使用 networkx 及其 connected_components。但是,我不确定如何将其扩展到多列。 - Shaido
@Shaido,能否提供一个最小的示例? - mr.bjerre
1
@mr.bjerre 你可以在这里看到如何找到分组:https://stackoverflow.com/questions/45086731/how-to-group-a-pandas-dataframe-which-has-a-list-of-combinations 然后,你可以创建一个字典并将旧列中的一列转换为分组列。但是,就我所知,它只适用于两列:/ - Shaido
显示剩余3条评论
1个回答

0

正如原帖中评论所建议的那样,可以使用 networkx 来解决问题。

import networkx as nx
import pandas as pd

df = pd.DataFrame({
    'id': range(1, 10),
    'mfr': ('a', 'b', 'a', 'c', 'd', 'e', 'd', 'd', 'f'),
    'vmn': ('A', 'A', 'B', 'C', 'D', 'E', 'F', 'F', 'D')
})

G = nx.from_pandas_edgelist(df, 'mfr', 'vmn')
Gcc = nx.connected_components(G)

connected_map = dict()
for g, ids in enumerate(Gcc):
    for id in ids:
        connected_map[id] = g

df['combined_group'] = df['mfr'].map(connected_map)

这将产生

   id mfr vmn  combined_group
0   1   a   A               0
1   2   b   A               0
2   3   a   B               0
3   4   c   C               1
4   5   d   D               2
5   6   e   E               3
6   7   d   F               2
7   8   d   F               2
8   9   f   D               2

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