熊猫:加入有条件的数据框

Posted

技术标签:

【中文标题】熊猫:加入有条件的数据框【英文标题】:Pandas: Join dataframe with condition 【发布时间】:2017-10-20 04:27:53 【问题描述】:

所以我有这个数据框(如下所示),我试图通过将其复制到另一个 df 来加入自己。加盟条件如下; 加盟条件:

    PERSONID 和 Badge_ID 相同 但不同的 SITE_ID1 两行之间的时间差应小于 48 小时。

期待

PERSONID    Badge_ID    Reader_ID1_x    SITE_ID1_x  EVENT_TS1_x         Reader_ID1_y    SITE_ID1_x  EVENT_TS1_y
2553-AMAGID 4229        141                 99          2/1/2016 3:26   145                 97          2/1/2016 3:29
2553-AMAGID 4229        248                 99          2/1/2016 3:26   145                 97          2/1/2016 3:29
2553-AMAGID 4229        145                 97          2/1/2016 3:29   251                 99          2/1/2016 3:29
2553-AMAGID 4229        145                 97          2/1/2016 3:29   291                 99          2/1/2016 3:29

这就是我累的地方, 制作 df 的副本,然后使用下面的条件过滤每个 df,然后再次加入它们。但是以下条件不起作用:( 在读入 df 之前,我在 SQL 中尝试了这个过滤器,但这对于 600k+ 行、带索引的事件来说太慢了。

df1 = df1[(df1['Badge_ID']==df2['Badge_ID']) and (df1['SITE_ID1']!=df2['SITE_ID1']) and ((df1['EVENT_TS1']-df2['EVENT_TS1'])<=datetime.timedelta(hours=event_time_diff))]

PERSONID    Badge_ID    Reader_ID1  SITE_ID1              EVENT_TS1
2553-AMAGID     4229    141             99          2/1/2016 3:26:10 AM
2553-AMAGID     4229    248             99          2/1/2016 3:26:10 AM
2553-AMAGID     4229    145             97          2/1/2016 3:29:56 AM
2553-AMAGID     4229    251             99          2/1/2016 3:29:56 AM
2553-AMAGID     4229    291             99          2/1/2016 3:29:56 AM
2557-AMAGID     4219    144             99          2/1/2016 2:36:30 AM
2557-AMAGID     4219    144             99          2/1/2016 2:40:00 AM
2557-AMAGID     4219    250             99          2/1/2016 2:40:00 AM
2557-AMAGID     4219    290             99          2/1/2016 2:40:00 AM
2557-AMAGID     4219    144             97          2/1/2016 4:02:06 AM
2557-AMAGID     4219    250             99          2/1/2016 4:02:06 AM
2557-AMAGID     4219    290             99          2/1/2016 4:02:06 AM
2557-AMAGID     4219    250             97          2/2/2016 1:36:30 AM
2557-AMAGID     4219    290             99          2/3/2016 2:38:30 AM
2559-AMAGID     4227    141             99          2/1/2016 4:33:24 AM
2559-AMAGID     4227    248             99          2/1/2016 4:33:24 AM
2560-AMAGID     4226    141             99          2/1/2016 4:10:56 AM
2560-AMAGID     4226    248             99          2/1/2016 4:10:56 AM
2560-AMAGID     4226    145             99          2/1/2016 4:33:52 AM
2560-AMAGID     4226    251             99          2/1/2016 4:33:52 AM
2560-AMAGID     4226    291             99          2/1/2016 4:33:52 AM
2570-AMAGID     4261    141             99          2/1/2016 4:27:02 AM
2570-AMAGID     4261    248             99          2/1/2016 4:27:02 AM
2986-AMAGID     4658    145             99          2/1/2016 3:14:54 AM
2986-AMAGID     4658    251             99          2/1/2016 3:14:54 AM
2986-AMAGID     4658    291             99          2/1/2016 3:14:54 AM
2986-AMAGID     4658    144             99          2/1/2016 3:26:30 AM
2986-AMAGID     4658    250             99          2/1/2016 3:26:30 AM
2986-AMAGID     4658    290             99          2/1/2016 3:26:30 AM
4133-AMAGID     6263    142             99          2/1/2016 2:44:08 AM
4133-AMAGID     6263    249             99          2/1/2016 2:44:08 AM
4133-AMAGID     6263    141             34          2/1/2016 2:44:20 AM
4133-AMAGID     6263    248             34          2/1/2016 2:44:20 AM
4414-AMAGID     6684    145             99          2/1/2016 3:08:06 AM
4414-AMAGID     6684    251             99          2/1/2016 3:08:06 AM
4414-AMAGID     6684    291             99          2/1/2016 3:08:06 AM
4414-AMAGID     6684    145             22          2/1/2016 3:19:12 AM
4414-AMAGID     6684    251             22          2/1/2016 3:19:12 AM
4414-AMAGID     6684    291             22          2/1/2016 3:19:12 AM
4414-AMAGID     6684    145             99          2/1/2016 4:14:28 AM
4414-AMAGID     6684    251             99          2/1/2016 4:14:28 AM
4414-AMAGID     6684    291             99          2/1/2016 4:14:28 AM
4484-AMAGID     6837    142             99          2/1/2016 2:51:14 AM
4484-AMAGID     6837    249             99          2/1/2016 2:51:14 AM
4484-AMAGID     6837    141             99          2/1/2016 2:51:26 AM
4484-AMAGID     6837    248             99          2/1/2016 2:51:26 AM
4484-AMAGID     6837    141             99          2/1/2016 3:05:12 AM
4484-AMAGID     6837    248             99          2/1/2016 3:05:12 AM
4484-AMAGID     6837    141             99          2/1/2016 3:08:58 AM
4484-AMAGID     6837    248             99          2/1/2016 3:08:58 AM

【问题讨论】:

你的数据从什么开始? 显示的数据是我正在使用的数据,包含列 (PERSONID Badge_ID Reader_ID1 SITE_ID1 EVENT_TS1) 您能否展示一个较小的样本以及您期望得到的结果。我有一个可行的例子,但我没有真正的方法知道它是否是你想要的。您应该在该示例中包含超过 48 小时阈值且不在结果集中的行。 我刚刚添加了一个匹配示例,因为它们属于相同的 PersonID 和 Badge_ID 但不同的 Site_ID 并且在 48 小时内。可以有更多的组合,但只是举个例子。 @AndrewL 一张表中的 600k 行,同一张表上有一个笛卡尔积加起来很多。 【参考方案1】:

尝试以下方法:

# Transform data in first dataframe
df1 = pd.DataFrame(data)

# Save the data in another datframe
df2 = pd.DataFrame(data)

# Rename column names of second dataframe 
df2.rename(index=str, columns='Reader_ID1': 'Reader_ID1_x', 'SITE_ID1': 'SITE_ID1_x', 'EVENT_TS1': 'EVENT_TS1_x', inplace=True)

# Merge the dataframes into another dataframe based on PERSONID and Badge_ID
df3 = pd.merge(df1, df2, how='outer', on=['PERSONID', 'Badge_ID'])

# Use df.loc() to fetch the data you want
df3.loc[(df3.Reader_ID1 < df3.Reader_ID1_x) & (df3.SITE_ID1 != df3.SITE_ID1_x) & (pd.to_datetime(df3['EVENT_TS1']) - pd.to_datetime(df3['EVENT_TS1_x'])<=datetime.timedelta(hours=event_time_diff))]

【讨论】:

以上是关于熊猫:加入有条件的数据框的主要内容,如果未能解决你的问题,请参考以下文章

While循环加入熊猫数据框

根据列值加入熊猫数据框

根据线序加入两个熊猫数据框

熊猫枢轴并加入两个数据框

无法加入熊猫中的数据框

熊猫有条件地创建系列/数据框列