Pandas合并不平等

mgdq6dx1  于 2023-09-29  发布在  其他
关注(0)|答案(2)|浏览(81)

所以我一直在搜索与这个SQL查询等价的pandas

SELECT * FROM table1
LEFT JOIN table2
ON table1.columnX>=table2.columnY

*请注意,我是通过不等式条件>=连接的,而不是通过匹配列。

但似乎Pandas的合并只能通过精确匹配来加入(如select * from table1 LEFT JOIN table2 ON table1.columnX=table2.columnY
它似乎不支持通过更复杂的条件进行连接,比如一列的值大于另一列。支持哪种SQL
我发现很多资源都说它不支持这一点,唯一的方法是先做一个cartersian产品,然后过滤得到的 Dataframe 。或者在加入之前预过滤 Dataframe 。然而,笛卡尔积是昂贵的
但我找到的这些来源是5年前的。panda的merge只能通过精确匹配列来连接,并且不允许不等式(<,>,<=,>=,between),这在今天仍然是一样的吗?
以下是我在这方面找到的一些旧资源:
Inequality joins in Pandas?
Merge pandas dataframes where one value is between two others
在pandas中按范围连接/合并的最佳方式

cbwuti44

cbwuti441#

conditional_join有效地覆盖了不等式连接(在引擎盖下,它使用二进制搜索)

# pip install pyjanitor
import pandas as pd
import janitor
from janitor import col
``
# code adapted from
# https://stackoverflow.com/a/44601120/7175713
table1 = pd.DataFrame(dict(
        columnX=range(5),
        value=range(5, 105, 21)
     ))
table2 = pd.DataFrame(dict(
        columnY=range(3),
        low=[0, 30, 30],
        high=[10, 40, 50]
   ))

table1
   columnX  value
0        0      5
1        1     26
2        2     47
3        3     68
4        4     89

table2
   columnY  low  high
0        0    0    10
1        1   30    40
2        2   30    50

table1.conditional_join(table2, col('columnX') >= col('columnY'))
    columnX  value  columnY  low  high
0         0      5        0    0    10
1         1     26        0    0    10
2         1     26        1   30    40
3         2     47        0    0    10
4         2     47        1   30    40
5         2     47        2   30    50
6         3     68        0    0    10
7         3     68        1   30    40
8         3     68        2   30    50
9         4     89        0    0    10
10        4     89        1   30    40
11        4     89        2   30    50

table1.conditional_join(table2, ('columnX','columnY','>='))
    columnX  value  columnY  low  high
0         0      5        0    0    10
1         1     26        0    0    10
2         1     26        1   30    40
3         2     47        0    0    10
4         2     47        1   30    40
5         2     47        2   30    50
6         3     68        0    0    10
7         3     68        1   30    40
8         3     68        2   30    50
9         4     89        0    0    10
10        4     89        1   30    40
11        4     89        2   30    50

范围连接也可以有效地实现,如果你安装了numba,你可以得到加速:

table1.conditional_join(table2, col('value') > col('low'), col('value') < col('high'))
   columnX  value  columnY  low  high
0        0      5        0    0    10
1        2     47        2   30    50

table1.conditional_join(table2, ('value','low','>'), ('value', 'high', '<'))
   columnX  value  columnY  low  high
0        0      5        0    0    10
1        2     47        2   30    50

如果你只是寻找第一个匹配,其中columnX >= columnY,那么pd.merge_asof也可以很好地覆盖你:

pd.merge_asof(table1, table2, left_on = 'columnX', right_on='columnY')
   columnX  value  columnY  low  high
0        0      5        0    0    10
1        1     26        1   30    40
2        2     47        2   30    50
3        3     68        2   30    50
4        4     89        2   30    50

注意,对于pd.merge_asof,连接列应该排序; conditional_join在引擎盖下处理这个问题。

vh0rcniy

vh0rcniy2#

在Pandas中,merge函数主要用于基于列之间的精确匹配进行组合。

您可以使用此代码作为示例:

import pandas as pd

# Sample data
data1 = {'columnX': [10, 15, 20]}
data2 = {'columnY': [5, 12, 18]}

df1 = pd.DataFrame(data1)
df2 = pd.DataFrame(data2)

# Perform a cartesian product
cartesian = pd.merge(df1.assign(key=1), df2.assign(key=1), on='key').drop('key', axis=1)

# Filter based on inequality condition
result_df = cartesian[cartesian['columnX'] >= cartesian['columnY']]

print(result_df)

相关问题