当前位置: 首页 > 面试题库 >

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

董小林
2023-03-14
问题内容

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

>>> 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. 您将如何产生相同的“左外部连接”?


问题答案:

我使用ufunc的外部方法来计算结果,这是示例:

首先,一些数据

import pandas as pd
import numpy as np
df_a = pd.DataFrame([{"a": 1, "b": 4}, {"a": 2, "b": 5}, {"a": 3, "b": 6}, {"a": 4, "b": 8}, {"a": 1, "b": 7}])
df_b = pd.DataFrame([{"c": 2, "d": 7}, {"c": 3, "d": 8}, {"c": 2, "d": 10}])
print "df_a"
print df_a
print "df_b"
print df_b

输出:

df_a
   a  b
0  1  4
1  2  5
2  3  6
3  4  8
4  1  7
df_b
   c   d
0  2   7
1  3   8
2  2  10

内部联接,因为这仅计算c&的笛卡尔积a内存使用率小于整个DataFrame的笛卡尔积:

ia, ib = np.where(np.less.outer(df_a.a, df_b.c))
print pd.concat((df_a.take(ia).reset_index(drop=True), 
                 df_b.take(ib).reset_index(drop=True)), axis=1)

输出:

   a  b  c   d
0  1  4  2   7
1  1  4  3   8
2  1  4  2  10
3  2  5  3   8
4  1  7  2   7
5  1  7  3   8
6  1  7  2  10

要计算左外部联接,请使用numpy.setdiff1d()查找df_a不在内部联接中的所有行:

na = np.setdiff1d(np.arange(len(df_a)), ia)
nb = -1 * np.ones_like(na)
oa = np.concatenate((ia, na))
ob = np.concatenate((ib, nb))
print pd.concat([df_a.take(oa).reset_index(drop=True), 
                 df_b.take(ob).reset_index(drop=True)], axis=1)

输出:

   a  b   c   d
0  1  4   2   7
1  1  4   3   8
2  1  4   2  10
3  2  5   3   8
4  1  7   2   7
5  1  7   3   8
6  1  7   2  10
7  3  6 NaN NaN
8  4  8 NaN NaN


 类似资料:
  • 问题内容: 给定两个数据帧,如下所示: 我们想使用非简化的标准来生成两个数据框的SQL风格的联接,比如说“ df_b.c> df_a.a”。据我所知,虽然肯定是解决方案的一部分,但我不能直接使用它,因为它不接受“ ON”条件的任意表达式(除非我遗漏了什么?)。 在SQL中,结果如下所示: 我目前用于内部联接的方法是,通过向两者都添加一列“ 1”,然后在“ 1”列上使用merge(),然后应用“ c

  • 我想使用Hibernate条件语言编写此查询。我对Hibernate很陌生,无法将此查询转换为条件形式。我参考了很多关于 SO 的答案,但就我而言,我在不同的列上使用内部连接而不是主键/外键列。我提到了这个,但仍然不能正确。

  • SQL Server 2000 使用20多个视图,所有视图都与table1(id和value1以及value2)进行内部连接 表1 或 表2 从表1中,value1或value2应始终为null。现在的问题是,如果value1或value2列为null,则输出显示为null,因为所有视图都是id为value1、value2的内部联接 我想使用条件进行内部联接,如果value1不为null,则使用v

  • 问题内容: 我想要一种改进我的sql代码的好方法,当条件满足时,我必须使用内部联接。我目前正在复制代码: 我想以这种方式做到这一点: 编辑: 解决方案(由于@Damien_The_Unbeliever): 问题答案: 这应该(大约)执行相同的操作: 当然,这还意味着必须编写对其中的列的任何其他引用,以期望此类列为。

  • 问题内容: 我试图在一个列上内部联接两个表。从数据库方面来看,没有映射,因为这是我不想讨论的。 我想使用INNER JOIN执行HQL查询并检索ROLE对象/结果。 到目前为止,这是我的总部 session.createQuery(“ ROLE作为角色,INNER JOIN INVOLVEMENT作为参与角色,id。X =参与.roleid WHERE参与.id = X”)。list(); 我看到

  • 问题内容: 有人可以验证内部连接对PL SQL中的UPDATE语句是否有效吗?例如 问题答案: 该synthax在Oracle SQL中不起作用。 在Oracle中,如果表是“键保留”的,则可以更新联接,即: 假设这是的主键,则此连接是可更新的,因为对于A的每一行,B 最多 只有一行,因此该更新是确定性的。 在您的情况下,由于更新后的值不依赖于另一个表,因此您可以使用具有EXIST条件的简单更新,

  • 问题内容: 如何将条件逻辑应用于Pandas DataFrame。 请参见下面显示的DataFrame, 我的原始数据显示在“数据”列中,并且期望的输出显示在其旁边。如果“数据”中的数字小于2.5,则所需的输出为False。 我可以应用循环并重新构建DataFrame …但是那是“非Python的” 问题答案: 只需将列与该值进行比较:

  • 问题内容: 有没有一种方法可以使用VLOOKUP内部联接两个不同的Excel电子表格? 在SQL中,我可以这样进行: 工作表1: 工作表2: 结果将是: 如何在VLOOKUP中执行此操作?还是除了VLOOKUP之外还有更好的方法吗? 谢谢。 问题答案: 首先,让我们获取两个表中都存在的值的列表。如果您使用的是excel 2010或更高版本,则在工作表3 A2中输入以下公式: 如果您使用的是2007