我经常使用pandas通过范围条件进行合并(连接)。
例如,如果有两个 Dataframe :
A(A_id,A_value)
B(B_id,B_low,B_high,B_name)
它们很大并且大小大致相同(假设每个记录为2 M)。
我想在A和B之间建立一个内部连接,所以A_value将在B_low和B_high之间。
使用的SQL语法为:
SELECT *
FROM A,B
WHERE A_value between B_low and B_high
这将是非常简单,简短和有效的。
同时,在pandas中,唯一的方法(不是使用我发现的循环)是在两个表中创建一个虚拟列,在其上连接(相当于交叉连接),然后过滤掉不需要的行。这听起来既沉重又复杂:
A['dummy'] = 1
B['dummy'] = 1
Temp = pd.merge(A,B,on='dummy')
Result = Temp[Temp.A_value.between(Temp.B_low,Temp.B_high)]
我的另一个解决方案是通过使用B[(x>=B.B_low) & (x<=B.B_high)]
掩码在每个A值上应用B上的搜索函数,但这听起来效率也很低,可能需要索引优化。
是否有更优雅和/或更有效的方法来执行此操作?
6条答案
按热度按时间sycxhyv71#
设置
考虑嵌套
A
和B
numpy
最简单的方法是使用
numpy
广播。我们寻找
A_value
大于或等于B_low
的每个示例,同时A_value
小于或等于B_high
。为了解决注解问题并给予类似于左连接的东西,我附加了
A
中不匹配的部分。qyswt5oh2#
不确定这样是否更有效,但是你可以直接使用sql(例如从模块sqlite3)和pandas(灵感来自this question),比如:
您可以根据应用程序的需要调整查询
pzfprimi3#
我不知道它的效率有多高,但有人写了一个 Package 器,允许你对pandas对象使用SQL语法。这就是所谓的pandasql。文档明确声明支持连接。这可能至少更容易阅读,因为SQL语法非常易读。
cyvaqqii4#
来自pyjanitor的conditional_join以高性能和高效的方式解决了这个问题,使用二进制搜索,而不是交叉连接:
内部联接
LEFT JOIN
g2ieeal75#
举一个简单的例子:
返回
现在让我们定义第二个 Dataframe
导致
开始;我们希望输出为索引3和A值5
导致
xqkwcwgp6#
我知道这是一个老问题,但对于新手来说,现在有一个pandas.merge_asof函数,它根据最接近的匹配执行连接。
如果你想合并一个DataFrame(
df_right
)的一个列在另一个DataFrame(df_left
)的两个列之间,你可以这样做:首先,找到右DataFrame的匹配项,这些匹配项最接近左DataFrame的左边界(
time_from
),但比左DataFrame的左边界(time_from
)大:正如你所看到的,索引2中的候选匹配是错误的,因为16不在10和15之间。
然后,找到右DataFrame的匹配项,这些匹配项最接近但小于左DataFrame的右边界(
time_to
):最后,保持候选匹配相同的匹配,这意味着右DataFrame的值在左DataFrame的2列值之间: