给定多个条件,将匹配值从一个df复制到另一个

时间:2019-12-13 22:25:11

标签: python pandas dataframe apply

我有两个数据框。第一个df1具有非唯一ID和以ms为单位的时间戳记值。另一个df2具有非唯一ID,单独的唯一ID,开始时间和结束时间(均以毫秒为单位)。

我需要从df2获取df1中每一行的正确唯一ID。我会通过...

  1. 将df1中的每个非唯一ID与df2中的相关行系列进行匹配
  2. 在这些行中,找到包含df1中时间戳的开始和结束范围的行
  3. 从结果行中获取唯一ID,并将其复制到df1中的新列

我认为我不能使用pd.merge,因为我需要将df1时间戳与df2中的两个不同列进行比较。我认为df.apply是我的答案,但我无法弄清楚。

以下是一些伪代码:

df1_dict = {
    'nonunique_id': ['abc','def','ghi','jkl'],
    'timestamp': [164.3,2071.2,1001.7,846.4]
}

df2_dict = {
    'nonunique_id': ['abc','abc','def','def','ghi','ghi','jkl','jkl'],
    'unique_id': ['a162c1','md85k','dk102','l394j','dj4n5','s092k','dh567','57ghed0'],
    'time_start': [160,167,2065,2089,1000,1010,840,876],
    'time_end': [166,170,2088,3000,1009,1023,875,880]
}

df1 = pd.DataFrame(data=df1_dict)
df2 = pd.DataFrame(data=df2_dict)

这是一个手动测试...

df2['unique_id'][(df2['nonunique_id'].eq('abc')) & (df2['time_start']<=164.3) & (df2['time_end']>=164.3)]

...将返回预期的输出(df2中的相关唯一ID):

  

0 a162c1

     

名称:unique_id,dtype:对象

我想要一个可以自动应用上述手动测试,然后将结果复制到df1中新列的功能。

我尝试过了...

def unique_id_fetcher(nonunique_id,timestamp):
    cond_1 = df2['nonunique_id'].eq(nonunique_id)
    cond_2 = df2['time_start']<=timestamp
    cond_3 = df2['time_end']>=timestamp

    unique_id = df2['unique_id'][(cond_1) & (cond_2) & (cond_3)]

    return unique_id

df1['unique_id'] = df1.apply(unique_id_fetcher(df1['nonunique_id'],df1['timestamp']))

...但是结果是:

  

ValueError:只能比较标记相同的Series对象

为清楚起见而编辑

1 个答案:

答案 0 :(得分:0)

IIUC,

您可以对两个数据框都做一个凯特式积,然后进行合并,然后应用逻辑

您创建一个字典,并使用non_unique_id作为键将值映射回df1。

df1['key'] = 'var'
df2['key'] = 'var'
df3 = pd.merge(df1,df2,on=['key','nonunique_id'],how='outer')

df4 = df3.loc[
    (df3["timestamp"] >= df3["time_start"]) & (df3["timestamp"] <= df3["time_end"])
]

d = dict(zip(df4['nonunique_id'],df4['unique_id']))

df1['unique_id'] = df1['nonunique_id'].map(d)

print(df1.drop('key',axis=1))

  nonunique_id  timestamp unique_id
0          abc      164.3    a162c1
1          def     2071.2     dk102
2          ghi     1001.7     dj4n5
3          jkl      846.4     dh567