Pandas:在多列中查找具有匹配值的行的Pythonic方法(分层条件)

抱歉标题有点不清楚。言语使我无法简洁地描述这个问题。希望我下面的描述可以帮助澄清。欢迎对标题进行任何澄清编辑。

我正在尝试从 Pandas 数据帧创建 networkx 流程图。数据框记录订单如何流经多家公司。数据框中的大多数行都是连接的,并且连接表现在多列中。样本数据如下:

df = pd.DataFrame({'Company': ['A', 'A', 'B', 'B', 'B', 'C', 'C'],
              'event_type':['new', 'route', 'receive', 'execute', 'route', 'receive', 'execute'],
             'event_id': ['110', '120', '200', '210', '220', '300', '310'],
             'prior_event_id': [np.nan, '110', np.nan, '120', '210', np.nan, '300'],
             'route_id': [np.nan, 'foo', 'foo', np.nan, 'bar', 'bar', np.nan]}
             )

数据框如下所示:

  Company event_type event_id prior_event_id route_id
0       A        new      110            NaN      NaN
1       A      route      120            110      foo
2       B    receive      200            NaN      foo
3       B    execute      210            120      NaN
4       B      route      220            210      bar
5       C    receive      300            NaN      bar
6       C    execute      310            300      NaN

订单经过 3 个公司:A、B、C。并且在每个公司内,后面的事件可以通过event_id-prior_event_id对链接到其源事件。但是这种方法不适用于属于不同公司的记录。例如,第 1 行和第 2 行将仅通过一列匹配route_id。因此,我试图重新创建的链接机制是一种层次结构,因为route_id如果event_id-prior_event_id列对没有产生任何结果,我将只使用列进行匹配。

下图可能有助于说明链接机制:

我的解决方案很笨拙:

# Make every event unique so as to not confound the linking
df['event_sub'] = df.groupby(df.event_type).cumcount()+1 
df['event'] = df.event_type + ' ' + df.event_sub.astype(str) 

# Find the match based on first matching criterion
replace_dict_event = dict(df[['event_id', 'event']].values)
df['source'] = df['prior_event_id'].apply(lambda x: replace_dict_event.get(x) if replace_dict_event.get(x) else np.nan )
df['target'] = df['event_id'].apply(lambda x: replace_dict_event.get(x) if replace_dict_event.get(x) else np.nan )

# From last step, find the match based on second matching criterion for the unmatched rows 
replace_dict_rtd = dict(df[df.event_type == 'route'][['route_id', 'event']].values)
df.loc[df.event_type == 'receive', 'source'] = df[df.event_type == 'receive']['route_id'].apply(lambda x: replace_dict_rtd.get(x))
df

我基本上使用了apply两次来逐步进行匹配。我想知道是否有更干净、更 Pythonic 的方法来做到这一点。

我的结果如下所示:

我由此创建的 networkx 图:

以上是Pandas:在多列中查找具有匹配值的行的Pythonic方法(分层条件)的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>