pandas 检测DataFrame的两列中是否存在反向对

3htmauhk  于 2023-05-12  发布在  其他
关注(0)|答案(2)|浏览(124)

我有一个两列的 Dataframe ; sourcetarget。我想要检测逆行,即对于一对值(source, target),如果存在一对值(target, source),则将True分配给新列。
我的尝试:

cols = ['source', 'target']
_cols = ['target', 'source']
sub_edges = edges[cols]
sub_edges['oneway'] = sub_edges.apply(lambda x: True if x[x.isin(x[_cols])] else False, axis=1)
u5i3ibmn

u5i3ibmn1#

您可以使用与示例中类似的逻辑应用lambda函数。我们检查dataframe中是否有任何行具有反向的源/目标对。
顺便说一句,列名“oneway”在我看来与你的问题中描述的逻辑相反,但是要改变这一点,我们可以删除lambda函数中的not

代码

import pandas as pd
import random

edges = {"source": random.sample(range(20), 20),
         "target": random.sample(range(20), 20)}

df = pd.DataFrame(edges)

df["oneway"] = df.apply(
    lambda x: not df[
        (df["source"] == x["target"]) & (df["target"] == x["source"]) & (df.index != x.name)
    ].empty,
    axis=1,
)

输出

source  target  oneway
0        9      11   False
1       16       1    True
2        1      16    True
3       11      14   False
4        4      13   False
5       18      15   False
6       14      17   False
7       13      12   False
8       19      19   False
9       12       3   False
10      10       6   False
11      15       5   False
12       3      18   False
13      17       0   False
14       6       7   False
15       5      10   False
16       7       2   False
17       8       9   False
18       0       4   False
19       2       8   False
3j86kqsm

3j86kqsm2#

另一个稍微快一点的方法,使用pandas pivot和melt。

d = df.pivot(
    index='source', 
    columns='target'
).fillna(0)

index = d.index.union(d.columns)
d = d.reindex(index=index, columns=index, fill_value=0)

e = (
    (d + d.T)
    .rename_axis('source', axis=0)
    .rename_axis('target', axis=1)
).reset_index().melt('source')

e[e.value == 2].sort_values(by=['source', 'target'])

这将显示你的边列表中的第一阶循环。

相关问题