如何在非简单条件下使用熊猫对DataFrame进行内部或外部联接

 

问题描述:

给定两个数据帧,如下所示:

>>> import pandas as pd

>>> df_a = pd.DataFrame([{"a": 1, "b": 4}, {"a": 2, "b": 5}, {"a": 3, "b": 6}])
>>> df_b = pd.DataFrame([{"c": 2, "d": 7}, {"c": 3, "d": 8}])
>>> df_a
   a  b
0  1  4
1  2  5
2  3  6

>>> df_b
   c  d
0  2  7
1  3  8

我们希望使用非简化的标准来生成两个数据框的SQL样式的联接,比如说“ df_b.c>
df_a.a”。据我所知,虽然merge()肯定是解决方案的一部分,但我不能直接使用它,因为它不接受“ ON”条件的任意表达式(除非我遗漏了什么?)。

在SQL中,结果如下所示:

# inner join
sqlite> select * from df_a join df_b on c > a;
1|4|2|7
1|4|3|8
2|5|3|8

# outer join
sqlite> select * from df_a left outer join df_b on c > a;
1|4|2|7
1|4|3|8
2|5|3|8
3|6||

我目前用于内部联接的方法是通过将两个都添加“ 1”的列,然后在“ 1”列上使用merge(),然后应用“ c>
a”,来生成df_a和df_b的笛卡尔积。标准。

>>> import numpy as np
>>> df_a['ones'] = np.ones(3)
>>> df_b['ones'] = np.ones(2)
>>> cartesian = pd.merge(df_a, df_b, left_on='ones', right_on='ones')
>>> cartesian
   a  b  ones  c  d
0  1  4     1  2  7
1  1  4     1  3  8
2  2  5     1  2  7
3  2  5     1  3  8
4  3  6     1  2  7
5  3  6     1  3  8
>>> cartesian[cartesian.c > cartesian.a]
   a  b  ones  c  d
0  1  4     1  2  7
1  1  4     1  3  8
3  2  5     1  3  8

对于外部联接,我不确定最好的方法,到目前为止,我一直在尝试获取内部联接,然后应用条件的求反获得所有其他行,然后尝试编辑该“求反”设置为原始图片,但实际上并没有用。

编辑 。HYRY在这里回答了具体问题,但我需要在Pandas
API中更通用,更通用的东西,因为我的加入标准可以是任何东西,而不仅仅是一个比较。对于外部联接,首先我要在“左侧”添加一个额外的索引,在执行内部联接后该索引将自行维护:

df_a['_left_index'] = df_a.index

然后我们进行笛卡尔运算并获得内部联接:

cartesian = pd.merge(df_a, df_b, left_on='ones', right_on='ones')
innerjoin = cartesian[cartesian.c > cartesian.a]

然后在“ df_a”中获取我们需要的其他索引ID,并从“ df_a”中获取行:

remaining_left_ids = set(df_a['_left_index']).\
                    difference(innerjoin['_left_index'])
remaining = df_a.ix[remaining_left_ids]

然后我们使用一个直接的concat(),它将左侧的缺失列替换为“ NaN”(我以为它并没有这样做,但是我想是的):

outerjoin = pd.concat([innerjoin, remaining]).reset_index()

HYRY的想法是只对需要比较的cols进行笛卡尔运算,这基本上是正确的答案,尽管在我的特定情况下,实现(一般化和全部化)可能会有些棘手。

问题:

  1. 您将如何在“ c> a”上产生df_1和df_2的“ join”?您会采用相同的“笛卡尔积,滤波”方法还是有更好的方法?

  2. 您将如何产生相同的“左外部连接”?


有没有一种简单的方法可以使用Python / NumPy /Scipy在图像上计算运行方差过滤器?通过运行方差图像,我的意思是为图像中每个子窗口I计算sum((I-mean(I))^ 2)/ nPixels的结果。 ...