在Python中复制SQL的"Join"

dan*_*ews 3 python numpy

我正在尝试从R切换到Python(主要是关于一般灵活性的问题).使用Numpy,matplotlib和ipython,除了合并"数据集"之外,我还能够覆盖我的所有用例.我想纯粹在python中模拟SQL的join by子句(inner,outer,full).R使用'merge'函数处理它.

我已经尝试了numpy.lib.recfunctions join_by,但它与'key'重复的关键问题:


join_by(key, r1, r2, jointype='inner', r1postfix='1', r2postfix='2',
        defaults=None, usemask=True, asrecarray=False)
Run Code Online (Sandbox Code Playgroud)

加入数组r1r2key.

密钥应该是字符串或与用于连接数组的字段对应的字符串序列.如果key在两个输入数组中找不到该字段,则会引发异常.

既不存在r1也不r2应该有任何重复key:重复的存在将使输出非常不可靠.请注意,算法不会查找重复项.

来源:http://presbrey.mit.edu:1234/numpy.lib.recfunctions.html


任何指针或帮助将非常感谢!

Ale*_*lli 6

假设您在Python中表示SQL表的等价物作为dicts列表,所有dicts都具有相同(假设字符串)键(其他表示形式,包括那些启用的表示numpy,可以在逻辑上归结为等效形式).现在,内部联接(再次,从逻辑的角度来看)他们的笛卡尔积的投影 - 在一般情况下,采用谓词参数on(从两个参数中获取两个参数,一个"记录"[[dict]] table,并且如果需要连接两个记录则返回true值,一个简单的方法是(使用每个表的前缀来消除歧义,以防止这两个表可能具有同等"字段"的风险):

def inner_join(tab1, tab2, prefix1, prefix2, on):
  for r1 in tab1:
    for r2 in tab2:
      if on(r1, r2):
        row = dict((prefix1 + k1, v1) for k1, v1 in r1.items())
        row.update((prefix2 + k2, v2) for k2, v2 in r2.items())
        yield row
Run Code Online (Sandbox Code Playgroud)

现在,当然你不想这样做,因为性能是O(M * N)- 但是,为了你已经指定的一般性("模拟SQL的连接子句(内部,外部,完整)"),实际上没有其他选择,因为a的ON条款JOIN是非常不受限制的.

对于外连接和完全连接,您还需要保留信息,以识别哪些记录[[来自一个或两个表]]尚未产生,否则产生 - 例如,对于左连接,您将添加一个bool,重置为yielded = False在之前for r2内环,设置为Trueyield内循环的执行方式,以及后if not yielded:,产生人造的(大概是用加入记录None放置NULL来代替缺失的v2值,因为没有r2实际使用为目的).

为了获得任何实质性的效率改进,你需要澄清你愿意遵守的关于on谓词和表格的unique约束- 我们已经从你的问题中知道你不能对任何一个表的键有限制,但是那里还有许多其他可能有帮助的约束,让我们猜测这种约束在你的情况下实际适用的是一个非常没有效果的努力.