在由成对的项目组成的约50万行的列表中,我试图建立一个文件,该文件旨在为每个项目分配与它们所属的组相关的ID。 进一步的解释如下。
我需要一些帮助,以一种聪明有效的方式(即pythonic)获得结果
==============
将输入文件df0转换为所需的输出 df2
例如,起始文件如下所示(但有50万个条目),其中item1与item2的关系由数据帧的结构决定。
df0:输入
df0 = pd.DataFrame({
"item 1": ['Q', 'R', 'B', 'A'],
"item 2": ['R', 'P', 'A', 'C']
})
其含义如下:项目Q与项目R相关,项目R与项目P相关,因此项目Q与项目P相关(与A,B和C相同)。在这种情况下,关系的可传递性导致建立两组项目。
由于对stackoverflow的其他贡献,我设法将所有可传递项分组为单个集合,并为它们分配一个单独的组号(或ID)。意思是我得到一个看起来像这样的数据框:
df1 = pd.DataFrame({
"items": [{'Q', 'R', 'P'}, {'B', 'A', 'C'} ],
"group": [1, 2]
})
上面的结果现在将被转换以支持进一步的数据后处理,并且预期的结果应如下所示:
df2:所需的输出
df2 = pd.DataFrame({
"items": ['Q', 'R', 'P', 'B', 'A', 'C' ],
"group": [1, 1, 1, 2, 2, 2 ]
})
==============
第1步::将df1.item转换为一系列单个项目
d = df1.item
e = list(sorted(set(chain.from_iterable(d))))
df2 = pd.DataFrame({'item':e})
第2步:'vlookup'df2.items通过df1.items返回df1.group
df2['group'] = ''
n = 0
for row in df2.items :
m = 0
for row in df1.items :
if df2['items'][n] in df1['items'][m]:
df2['group'][n] = df1['group'][m]
m = m + 1
n = n + 1
==============
它确实适用于小型表,但不适用于大型数据框。
我正在寻求有关以下方面的帮助:
非常感谢您的时间和反馈!
答案 0 :(得分:2)
IIUC,您可以尝试查看networkx
库。
您可以直接从pandas.DataFrame
创建一个非直接网络图,并使用connected_component_subgraphs
方法来提取子组:
<iframe src="../images/highLevelArchitecture.svg"></iframe>
使用列表推导功能为新的import networkx as nx
df0 = pd.DataFrame({'item 1': {0: 'Q', 1: 'R', 2: 'B', 3: 'A'},
'item 2': {0: 'R', 1: 'P', 2: 'A', 3: 'C'}})
g = nx.convert_matrix.from_pandas_edgelist(df0, source='item 1', target='item 2')
DataFrame