Объединенная группа с использованием панд - PullRequest
0 голосов
/ 11 сентября 2018

Представьте себе 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

Я хочу определить, какие id принадлежат друг другу, сгруппировав их по mfr и / или vmn. Я легко могу назначить идентификатор группы, используя один из других,

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 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 равны. Третья группа также относится к той же группе, поскольку строки 3 и 1 одинаковы для vmn. И так далее ...

Обратите внимание, что это будет выполняться на нескольких столбцах с большим количеством строк, поэтому производительность также будет высоко оценена.

1 Ответ

0 голосов
/ 11 сентября 2018

Как предлагается в комментариях в оригинальном сообщении, это можно решить с помощью 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...