Python pandas中pd.join(how=';left';)的意外结果
在计算机上使用jupyter笔记本 3.6.3 |蟒蛇定制(64位)|(默认,2017年10月15日,03:27:45)[MSC v.1900 64位(AMD64)] 考虑下面的简单示例:Python pandas中pd.join(how=';left';)的意外结果,python,sql,pandas,Python,Sql,Pandas,在计算机上使用jupyter笔记本 3.6.3 |蟒蛇定制(64位)|(默认,2017年10月15日,03:27:45)[MSC v.1900 64位(AMD64)] 考虑下面的简单示例: left = pd.DataFrame({'k': ['K0', 'K1', 'K2'], 'v': [1, 2, 3]}).set_index('k') right = pd.DataFrame({'k': ['K0', 'K0', 'K3'], 'v': [4, 5, 6]}).set_index('k'
left = pd.DataFrame({'k': ['K0', 'K1', 'K2'], 'v': [1, 2, 3]}).set_index('k')
right = pd.DataFrame({'k': ['K0', 'K0', 'K3'], 'v': [4, 5, 6]}).set_index('k')
right2 = pd.DataFrame({'v': [7, 8, 9]}, index=['K1', 'K1', 'K3'])
left
right
right2
left.join(right,how='left',lsuffix='_L',rsuffix='_R')
pd.merge(left,right,how='left',right_index=True,left_index=True)
到目前为止,一切都很好!最后两行产生了与预期相同的结果,但下面的行结果对我来说是相当意外的,因为它包含不属于left
数据帧的索引(结果似乎是外部联接):
我注意到它也使用了.merge
默认后缀,而不是我为.join
指定的后缀,我没有收到任何错误。为什么呢
当连接两个以上的数据帧时,也可以这样做,如下所示:
left.join([right,right2])
我不明白为什么结果包含不属于left
数据帧的索引,即使这是一个左连接
这可以在有关的pandas文档中看到
非常感谢 对于问题的第一部分(即:我注意到它也使用了.merge默认后缀,而不是我为.join指定的后缀,而且我没有收到任何错误。这是为什么?)我不知道为什么,但根据文档,它似乎是正确的:
Notes
-----
on, lsuffix, and rsuffix options are not supported when passing a list
of DataFrame objects
那么你问题的最后一部分我有点不知道。如果您检查
df.join()
的代码,则在使用列表时似乎是这样的…。您将看到,如果other
不是数据帧
或系列
,即列表
,在某个时候会发生这种情况:
# join indexes only using concat
if how == 'left':
how = 'outer'
join_axes = [self.index]
else:
join_axes = None
frames = [self] + list(other)
can_concat = all(df.index.is_unique for df in frames)
if can_concat:
return concat(frames, axis=1, join=how, join_axes=join_axes,
verify_integrity=True)
joined = frames[0]
for frame in frames[1:]:
joined = merge(joined, frame, how=how, left_index=True,
right_index=True)
return joined
因此,how='left'
更改为how='outer'
。我不知道为什么要这样做,但似乎是为了(正如评论所暗示的)做一些准备;concat只能处理“内部”或“外部”。但是在您的情况下,索引不是唯一的,代码底部的for循环被执行(但仍然使用how='outer')。这解释了您所看到的情况(与外部联接类似合并的行为)
当然,您也可以使用相同的策略,但如何在代码中直接使用='left'来执行一系列左连接:
joined = left
for frame in [right, right2]:
joined = pd.merge(joined, frame, how='left', left_index=True, right_index=True)
这是一种意想不到的行为,现已作为一种行为提交。
joined = left
for frame in [right, right2]:
joined = pd.merge(joined, frame, how='left', left_index=True, right_index=True)