【发布时间】:2021-05-08 14:25:49
【问题描述】:
我有一个 pandas DataFrame,其中包含我最终希望 连接 并变成类似对象的图形的节点行。为此,我首先想到将这个 DataFrame 转换为类似于邻接列表的东西,以便稍后轻松地从中创建一个图。我有以下内容:
熊猫数据框:
df = pd.DataFrame({"id": [0, 1, 2, 3, 4, 5, 6],
"start": ["A", "B", "D", "A", "X", "F", "B"],
"end": ["B", "C", "F", "G", "X", "X", "E"],
"cases": [["c1", "c2", "c44"], ["c2", "c1", "c3"], ["c4"], ["c1", ], ["c1", "c7"], ["c4"], ["c44", "c7"]]})
看起来像这样:
id start end cases
0 0 A B [c1, c2, c44]
1 1 B C [c2, c1, c3]
2 2 D F [c4]
3 3 A G [c1]
4 4 X X [c1, c7]
5 5 F X [c4]
6 6 B E [c44, c7]
一个函数directly_follows(i, j),如果i 行中的节点后跟j 行中的节点,则返回true(这稍后将成为从节点i 到节点j 的图中的有向边):
def directly_follows(row1, row2):
return close(row1, row2) and case_overlap(row1, row2)
def close(row1, row2):
return row1["end"] == row2["start"]
def case_overlap(row1, row2):
return not set(row1["cases"]).isdisjoint(row2["cases"])
简而言之,如果节点i 的end 值与节点j 的start 值相同并且它们的cases 重叠,则节点i 后跟节点j
基于这个directly_follows 函数,我想为我的DataFrame df 创建一个额外的列,它充当邻接列表,包含节点i 的列表,其中id 后面的节点的值是@ 987654340@
因此,我想要的结果是:
id start end cases adjacency_list
0 0 A B [c1, c2, c44] [1, 6]
1 1 B C [c2, c1, c3] []
2 2 D F [c4] [5]
3 3 A G [c1] []
4 4 X X [c1, c7] []
5 5 F X [c4] []
6 6 B E [c44, c7] []
基本上我想到了首先将列adjacency_list创建为空列表,然后循环遍历Dataframe的行,如果对于行i和j直接_follows(row_i,row_j)返回True,添加@的id 987654344@ 到i 的邻接列表。
我是这样做的:
def connect(data):
data["adjacency_list"] = np.empty((len(data), 0)).tolist()
for i in range(len(data)):
for j in range(len(data)):
if i != j:
if directly_follows(data.iloc[i], data.iloc[j]):
data.iloc[i]["adjacency_list"] = data.iloc[i]["adjacency_list"].append(data.iloc[i]["id"])
首先,这会返回一个错误
SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame
其次,我非常怀疑这是解决这个问题的最 Pythonic 和最有效的方法,因为我的实际 DataFrame 包含大约 9000 行,这将提供大约 8100 万次比较。
如何以最省时的方式创建邻接表?有没有比我的更快或更优雅的解决方案?
【问题讨论】:
-
这是单向的吗? 5 不与 4 相邻?
-
不,我想将每一行与每一行进行比较。第 4 行的结尾是“X”,第 5 行的开头是“F”,所以 4 后面没有 5
-
对,但第 5 行以“X”结尾,第 4 行以“X”开头。如果您将每一行与其他行进行比较,那么 5 是否不会连接到 4?
-
这是真的,如果他们确实在案例中重叠,但他们没有(我的其他连接要求)
标签: python pandas dataframe graph adjacency-list