我的目标是找出以下 df 是否有“循环”
给定:
df = pd.DataFrame({'From':['USA','UK','France','Italy','Russia','china','Japan','Australia','Russia','Italy'],
'to':['UK','France','Italy','Russia','china','Australia','New Zealand','Japan','USA','France']})
df
Run Code Online (Sandbox Code Playgroud)
如果我绘制它,它看起来像这样(最终,请注意 df 上的顺序是不同的):
USA-->UK-->France-->Italy-->Russia-->China-->Australia-->Japan-->Australia
| |
| |
France USA
Run Code Online (Sandbox Code Playgroud)
关键是:你不能倒退,所以意大利不能去法国,俄罗斯不能去美国。
注意:From可以有多个Tos
我可以在没有 pandas 的情况下解决它(我得到df.to_dict('records')然后迭代以找到循环,然后返回到 pandas),但我希望留在 pandas 上。
逻辑并不完全清楚,但是您可以用图表来解决您的问题。
你的图表如下:
让我们考虑一下循环节点,即那些具有多个目的地的节点。
您可以通过以下方式获取networkx:
import networkx as nx
G = nx.from_pandas_edgelist(df, source='From', target='to', create_using=nx.DiGraph)
circulating = {n for n in G if len(list(G.successors(n)))>1}
df['IS_CIRCULATING'] = df['From'].isin(circulating).astype(int)
Run Code Online (Sandbox Code Playgroud)
输出:
From to IS_CIRCULATING
0 USA UK 0
1 UK France 0
2 France Italy 0
3 Italy Russia 1
4 Russia china 1
5 china Australia 0
6 Japan New Zealand 0
7 Australia Japan 0
8 Russia USA 1
9 Italy France 1
Run Code Online (Sandbox Code Playgroud)
对于纯熊猫:
df['IS_CIRCULATING'] = df.groupby('From')['to'].transform('nunique').gt(1).astype(int)
Run Code Online (Sandbox Code Playgroud)