【问题标题】:Merge two dataframes on multiple keys with tolerance using merge_asof使用 merge_asof 在多个具有容差的键上合并两个数据帧
【发布时间】:2022-09-29 21:49:26
【问题描述】:

我们希望从两个数据帧中的多个键中找到最佳匹配。从文档中获取方法merge_asof似乎是一个合理的选择。测试一列它按预期工作。

import pandas as pd
import numpy as np
data_key_1 = np.arange(10).astype(float)
data_key_2 = np.arange(10).astype(float)
data_key_1_noisy = data_key_1-0.25*np.random.rand(10)
data_key_2_noisy = data_key_2-0.1*np.random.rand(10)
data_target = list(\'abcdefghij\')

# one key approach
df_1 = pd.DataFrame(zip(data_key_1[::2], ), columns=[\'key_1\',])
df_2 = pd.DataFrame(zip(data_key_1_noisy, data_target), columns=[\'key_1\', \'target\',])
df_result_1 = pd.merge_asof(df_1, df_2, on=\'key_1\', direction=\'nearest\', tolerance=0.5)
print(df_result_1)

控制台输出如下。

   key_1 target
0    0.0      a
1    2.0      c
2    4.0      e
3    6.0      g
4    8.0      i

尝试使用两个键时,它失败了。我们尝试了不同的关键字设置组合,但未能成功运行。

# two keys approach
df_1 = pd.DataFrame(zip(data_key_1[::2], data_key_2[::2]), columns=[\'key_1\', \'key2\'])
df_2 = pd.DataFrame(zip(data_key_1_noisy, data_key_2_noisy, data_target), columns=[\'key_1\', \'key2\', \'target\'])
df_result_2 = pd.merge_asof(df_1, df_2, on=[\'key_1\', \'key_2\'], direction=\'nearest\', tolerance=0.5)
print(df_result_2)

它会抛出一个错误:

pandas.errors.MergeError:只能在左键上

预期的控制台输出将是。

   key_1  key2 target
0    0.0   0.0      a
1    2.0   2.0      c
2    4.0   4.0      e
3    6.0   6.0      g
4    8.0   8.0      i

因此,我们质疑自己是否尝试在不适当的上下文中应用此方法,或者它是否是适用的用例而我们只是弄乱了关键字。

    标签: python pandas dataframe merge


    【解决方案1】:

    merge_asof 始终只有一个键(想想为什么它需要对键进行排序)。您可以合并一个键并过滤另一个键。

    (pd.merge_asof(df_1, df_2, on='key_1', direction='nearest', tolerance=0.5, suffixes=['','_'])
       # may need to drop duplicate on `key_1, key2` here based on `abs` as well
       .loc[lambda x: x['key2'].sub(x['key2_']).abs() < 0.5]
       .drop(columns=['key2_'])  
    )
    

    输出:

       key_1  key2 target
    0    0.0   0.0      a
    1    2.0   2.0      c
    2    4.0   4.0      e
    3    6.0   6.0      g
    4    8.0   8.0      i
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-27
      • 1970-01-01
      • 2020-10-08
      • 1970-01-01
      • 2021-01-06
      • 1970-01-01
      • 2018-07-25
      • 1970-01-01
      相关资源
      最近更新 更多