如何将相关子列表的唯一 ID 分配给共享评论元素的子列表的每个元素?
How to attribute to each elements of a sublist sharing comment elements the unique ID of the related sublist?
在由项目对组成的约 500k 行列表中,我正在尝试构建一个文件,旨在为每个项目分配与其所属组相关的 ID。 后面有进一步的解释。
我需要一些帮助才能以一种聪明有效的方式(即 pythonic)获得结果
==============
我想做什么
将输入文件df0转换成期望的输出df2
例如,起始文件看起来像这样(但有 500k 个条目),其中从 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同理)。在那种情况下,关系的传递性导致构建两组项目。
- 每个项目仅属于 1 个组。
- 在实际案例文件中,预计组最多可容纳 11 个项目。
- 字母顺序不起作用
感谢 Whosebug 上的其他贡献,我设法将所有可传递项目分组为单个集合,并为它们分配一个组号(或 ID)。意思是我得到一个看起来像这样的数据框:
df1 = pd.DataFrame({
"items": [{'Q', 'R', 'P'}, {'B', 'A', 'C'} ],
"group": [1, 2]
})
现在要转换上面的结果以支持进一步的数据 post-治疗,期望的结果应该如下所示:
df2:所需输出
df2 = pd.DataFrame({
"items": ['Q', 'R', 'P', 'B', 'A', 'C' ],
"group": [1, 1, 1, 2, 2, 2 ]
})
==============
到目前为止我做了什么
第一步:将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
==============
它适用于小表,但不适用于大型数据帧。
我正在寻求有关以下方面的帮助:
- 第 2 步的更好代码以增强 df2 (首选)
- 或跳过第 2 步并直接从 df1 中获取 df2 的更好方法
提前感谢您的宝贵时间和反馈!
IIUC,您可以尝试查看 networkx
库。
您可以直接从 pandas.DataFrame
and use the connected_component_subgraphs
方法创建一个非直接网络图来提取子组:
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
创建数据
subgroups = [(n, i + 1) for i, sg in enumerate(nx.connected_component_subgraphs(g)) for n in sg.nodes]
df2 = pd.DataFrame(subgroups, columns=['items', 'subgroup'])
print(df2)
items subgroup
0 P 1
1 R 1
2 Q 1
3 C 2
4 A 2
5 B 2
在由项目对组成的约 500k 行列表中,我正在尝试构建一个文件,旨在为每个项目分配与其所属组相关的 ID。 后面有进一步的解释。
我需要一些帮助才能以一种聪明有效的方式(即 pythonic)获得结果
==============
我想做什么
将输入文件df0转换成期望的输出df2
例如,起始文件看起来像这样(但有 500k 个条目),其中从 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同理)。在那种情况下,关系的传递性导致构建两组项目。
- 每个项目仅属于 1 个组。
- 在实际案例文件中,预计组最多可容纳 11 个项目。
- 字母顺序不起作用
感谢 Whosebug 上的其他贡献,我设法将所有可传递项目分组为单个集合,并为它们分配一个组号(或 ID)。意思是我得到一个看起来像这样的数据框:
df1 = pd.DataFrame({
"items": [{'Q', 'R', 'P'}, {'B', 'A', 'C'} ],
"group": [1, 2]
})
现在要转换上面的结果以支持进一步的数据 post-治疗,期望的结果应该如下所示:
df2:所需输出
df2 = pd.DataFrame({
"items": ['Q', 'R', 'P', 'B', 'A', 'C' ],
"group": [1, 1, 1, 2, 2, 2 ]
})
==============
到目前为止我做了什么
第一步:将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.groupdf2['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
==============
它适用于小表,但不适用于大型数据帧。
我正在寻求有关以下方面的帮助:
- 第 2 步的更好代码以增强 df2 (首选)
- 或跳过第 2 步并直接从 df1 中获取 df2 的更好方法
提前感谢您的宝贵时间和反馈!
IIUC,您可以尝试查看 networkx
库。
您可以直接从 pandas.DataFrame
and use the connected_component_subgraphs
方法创建一个非直接网络图来提取子组:
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
subgroups = [(n, i + 1) for i, sg in enumerate(nx.connected_component_subgraphs(g)) for n in sg.nodes]
df2 = pd.DataFrame(subgroups, columns=['items', 'subgroup'])
print(df2)
items subgroup
0 P 1
1 R 1
2 Q 1
3 C 2
4 A 2
5 B 2