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

Python 给定多个条件,将匹配值从一个df复制到另一个df,python,pandas,dataframe,apply,Python,Pandas,Dataframe,Apply,我有两个数据帧。第一个df1具有非唯一ID和时间戳值,单位为ms。另一个df2具有非唯一ID、单独的唯一ID、开始时间和结束时间(均以ms为单位) 我需要从df2中为df1中的每一行获取正确的唯一ID。我会通过 将df1中的每个非唯一ID与df2中的相关行序列相匹配 在这些行中,找到包含df1中时间戳的开始和结束范围的行 从结果行中获取唯一ID,并将其复制到df1中的新列 我认为我不能使用pd.merge,因为我需要将df1时间戳与df2中的两个不同列进行比较。我想df.apply是我的答案,但

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

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

  • 将df1中的每个非唯一ID与df2中的相关行序列相匹配
  • 在这些行中,找到包含df1中时间戳的开始和结束范围的行
  • 从结果行中获取唯一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['unique_id'][(df2['uniunique_id'].eq('abc'))和(df2['time_start']=164.3)]
    
    …返回预期输出(来自df2的相关唯一ID):

    0 a162c1

    名称:唯一\u id,数据类型:对象

    我想要一个可以自动应用上述手动测试的功能,并将结果复制到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']))
    
    def unique_id_fetcher(非unique_id,时间戳):
    cond_1=df2['ununique_id'].eq(ununique_id)
    cond_2=df2['time_start']=时间戳
    唯一id=df2['unique_id'][(cond_1)&(cond_2)&(cond_3)]
    返回唯一的\u id
    df1['unique_id']=df1.apply(unique_id_fetcher(df1['ununique_id'],df1['timestamp']))
    
    …但这会导致:

    ValueError:只能比较标签相同的系列对象

    (为清晰起见进行了编辑)

    IIUC

    您可以对这两个数据帧进行caretsian乘积并进行合并,然后应用您的逻辑

    您创建一个dict,并使用非唯一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
    
    df1['key']='var'
    df2['key']='var'
    df3=pd.merge(df1,df2,on=['key','ununique\u id',how='outer')
    df4=df3.loc[
    
    (df3[“timestamp”]>=df3[“time_start”])和(df3[“timestamp”]您的预期输出是什么?使用伪代码,我希望:
    0 a162c1
    名称:unique_id,数据类型:object
    (请参阅上面突出显示的第一块文本).一般来说,预期输出是df2中唯一的id。理解,添加了答案。是的!这是预期输出,谢谢。让我用这个方法坐一会儿。没问题,如果你需要任何其他解释,请告诉我,概念一点也不难!好的,这肯定为我指明了正确的方向!首先,我是真的我意识到进行合并然后删除的两步方法可能就是我所追求的,但我陷入了“必须有一步方法”的思维模式。现在,具体到您的代码:(1)我能够实现合并,而无需添加通用的“var”列;您能详细说明这些列的用途吗?,(2)在我的特定用例中,我不需要df1的干净版本,因此我可以在那里做所有事情,而不是创建额外的数据帧。TLDR:这就是我最后要做的。var的目的是创建一个合并的数据帧,其中包含两个数据帧的所有可能结果,在sql server和Cartesian join elsew中称为交叉连接在这里。你为什么不把你的解决方案作为答案发布呢?