【问题标题】:How to merge 2 dataframes based on two columns via string containment如何通过字符串包含基于两列合并 2 个数据帧
【发布时间】:2020-09-07 10:06:32
【问题描述】:

我的问题有点类似于这个问题:How to merge pandas on string contains?,但我需要不同的输出,而且问题本身有点复杂。所以我有 2 个类似于下面的数据框:

df1 = pd.DataFrame({'ref_name':['city-louisville','city-louisville','city-louisville', 'town-lexington','town-lexington','town-lexington'], 'un_name1':['CPU1','CPU2','GPU1','CPU1','CPU2','GPU1'], 'value1':[10,15,28,12,14,14]})

df2 = pd.DataFrame({'ref_name':['louisville','louisville','lexington','lexington'], 'un_name2':['CPU','GPU','CPU','GPU'], 'value2':[25,28,26,14]})

我需要基于ref_nameun_name 基于它们中的子字符串加入。它们不会总是像这样干净,但我认为它是一个不错的小例子。所以在这种情况下我想要的输出看起来像这样:

ref_name  |  un_name1  |  un_name2  | value1  |  value2
---------------------------------------------------------
louisville|  CPU1      |  CPU       |  10     |  25
louisville|  CPU2      |  CPU       |  15     |  25
louisville|  GPU1      |  GPU       |  28     |  28
lexington |  CPU1      |  CPU       |  12     |  26
lexington |  CPU2      |  CPU       |  14     |  26
lexington |  GPU1      |  GPU       |  14     |  14

提前感谢您对此的任何帮助!

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    这是我能想到的最通用的版本。如果您的数据框很大,性能可能会成为问题。

    mask1 = df2['ref_name'].apply(lambda value: df1['ref_name'].str.contains(value))
    mask2 = df2['un_name2'].apply(lambda value: df1['un_name1'].str.contains(value))
    mask = (mask1 & mask2).stack().rename_axis(['index2', 'index1'])
    mask = mask[mask].index.to_frame(False)
    
    result = mask.merge(df2, left_on='index2', right_index=True) \
                 .merge(df1, left_on='index1', right_index=True)
    

    结果:

     index2  index1  ref_name_x un_name2  value2       ref_name_y un_name1  value1
          0       0  louisville      CPU      25  city-louisville     CPU1      10
          0       1  louisville      CPU      25  city-louisville     CPU2      15
          1       2  louisville      GPU      28  city-louisville     GPU1      28
          2       3   lexington      CPU      26   town-lexington     CPU1      12
          2       4   lexington      CPU      26   town-lexington     CPU2      14
          3       5   lexington      GPU      14   town-lexington     GPU1      14
    

    修剪/重命名列是留给 OP 的练习。

    【讨论】:

    • 完美,谢谢!!是的,修剪多余的列完全没有问题,数据在上面的例子和我凌乱的数据集中都完美排列。也觉得我应该注意到它并没有花费太长时间来运行。对于 1 个具有 1000 个条目的数据帧和另一个具有 >6000 个条目的数据帧,花费了不到 10 秒。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-22
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 2019-12-29
    • 2021-08-25
    • 1970-01-01
    相关资源
    最近更新 更多