我有一個包含 3 列(約 1100 行,但可能或多或少)的 DataFrame。每列包含由長整陣列成的 ID,可以存在于多個行和列中。我需要將由至少一個公共 ID 鏈接的每一行以任何程度的分離合并(我發布了一個簡單的 DF 示例,應該澄清這部分)。我想出的唯一方法是花時間來計算。
#Dataframe:
A B C
X Y Z
D E F
T U V
C D E
E N Z
AA BB CC
HH CC U
#Final needed result (the order is irrelevant):
A B C D E F N Z X Y
T U V HH CC AA BB
uj5u.com熱心網友回復:
這將獲得您的示例的二分圖。
import networkx as nx
g = nx.Graph()
for _, row in df.iterrows():
a, b, c = row
# The given requirement is "linked by at least one common ID",
# so each row induces three edges.
g.add_edge(a, b)
g.add_edge(b, c)
g.add_edge(a, c)
現在enumerate_all_cliques()將恢復所需的連接組件,即使它開發的組件遠不止兩個。
uj5u.com熱心網友回復:
您可以使用 networkx 并找到連接的組件,如下所示:
import networkx as nx
from itertools import tee
#Using and itertools recipe, pairwise
def pairwise(iterable):
# pairwise('ABCDEFG') --> AB BC CD DE EF FG
a, b = tee(iterable)
next(b, None)
return zip(a, b)
df_p = pd.concat([df[[i[0], i[1]]].set_axis(['s', 'e'], axis=1) for i in pairwise(df)])
G = nx.from_pandas_edgelist(df_p, 's', 'e')
list(nx.connected_components(G))
輸出:
[{'A', 'B', 'C', 'D', 'E', 'F', 'N', 'X', 'Y', 'Z'},
{'AA', 'BB', 'CC', 'HH', 'T', 'U', 'V'}]
uj5u.com熱心網友回復:
這使用純 Python,應該相當高效,但可能不如使用 networkx 的解決方案高效。
import pandas as pd
df = pd.DataFrame(
r.strip().split()
for r in """
A B C
X Y Z
D E F
T U V
C D E
E N Z
AA BB CC
HH CC U
""".strip().splitlines()
)
# dict that will point to the matching cluster for each ID
id_cluster = dict()
for idx, row in df.iterrows():
# merge all the matching clusters into the first one
# note: we reuse the first one to avoid rebuilding the whole cluster
# each time if all the elements are already in the first one
new_cluster = id_cluster.get(row[0], {row[0]})
for id in row[1:]:
new_cluster.update(id_cluster.get(id, {id}))
# update all the IDs in this cluster to point to the correct cluster
# (there will only be one copy of new_cluster in memory, but they
# will all point to it, and Python will discard the old clusters)
for id in new_cluster:
id_cluster[id] = new_cluster
# show the unique clusters
# note: using frozenset() is an easy way to make the sets hashable
# so we can select only the unique ones via set()
result = [sorted(row) for row in set(map(frozenset, id_cluster.values()))]
print(result)
# [['AA', 'BB', 'CC', 'HH', 'T', 'U', 'V'],
# ['A', 'B', 'C', 'D', 'E', 'F', 'N', 'X', 'Y', 'Z']]
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/496096.html
上一篇:組合資料框以替換缺失值
