按索引合并两个数据框
- 2025-01-09 08:46:00
- admin 原创
- 93
问题描述:
我有以下数据框:
> df1
id begin conditional confidence discoveryTechnique
0 278 56 false 0.0 1
1 421 18 false 0.0 1
> df2
concept
0 A
1 B
如何合并索引以获得:
id begin conditional confidence discoveryTechnique concept
0 278 56 false 0.0 1 A
1 421 18 false 0.0 1 B
我之所以问这个问题,是因为据我了解,merge()
iedf1.merge(df2)
使用列来进行匹配。事实上,这样做我得到了:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/pandas/core/frame.py", line 4618, in merge
copy=copy, indicator=indicator)
File "/usr/local/lib/python2.7/dist-packages/pandas/tools/merge.py", line 58, in merge
copy=copy, indicator=indicator)
File "/usr/local/lib/python2.7/dist-packages/pandas/tools/merge.py", line 491, in __init__
self._validate_specification()
File "/usr/local/lib/python2.7/dist-packages/pandas/tools/merge.py", line 812, in _validate_specification
raise MergeError('No common columns to perform merge on')
pandas.tools.merge.MergeError: No common columns to perform merge on
在索引上合并是不是不好的做法?这不可能吗?如果是这样,我该如何将索引移到名为“索引”的新列中?
解决方案 1:
使用merge
,默认情况下为内连接:
pd.merge(df1, df2, left_index=True, right_index=True)
或者join
,默认情况下为左连接:
df1.join(df2)
或者concat
,默认情况下为外连接:
pd.concat([df1, df2], axis=1)
样品:
df1 = pd.DataFrame({'a':range(6),
'b':[5,3,6,9,2,4]}, index=list('abcdef'))
print (df1)
a b
a 0 5
b 1 3
c 2 6
d 3 9
e 4 2
f 5 4
df2 = pd.DataFrame({'c':range(4),
'd':[10,20,30, 40]}, index=list('abhi'))
print (df2)
c d
a 0 10
b 1 20
h 2 30
i 3 40
# Default inner join
df3 = pd.merge(df1, df2, left_index=True, right_index=True)
print (df3)
a b c d
a 0 5 0 10
b 1 3 1 20
# Default left join
df4 = df1.join(df2)
print (df4)
a b c d
a 0 5 0.0 10.0
b 1 3 1.0 20.0
c 2 6 NaN NaN
d 3 9 NaN NaN
e 4 2 NaN NaN
f 5 4 NaN NaN
# Default outer join
df5 = pd.concat([df1, df2], axis=1)
print (df5)
a b c d
a 0.0 5.0 0.0 10.0
b 1.0 3.0 1.0 20.0
c 2.0 6.0 NaN NaN
d 3.0 9.0 NaN NaN
e 4.0 2.0 NaN NaN
f 5.0 4.0 NaN NaN
h NaN NaN 2.0 30.0
i NaN NaN 3.0 40.0
解决方案 2:
您可以使用concat([df1, df2, ...], axis=1)来连接两个或多个按索引对齐的 DF:
pd.concat([df1, df2, df3, ...], axis=1)
或者通过自定义字段/索引进行合并:
# join by _common_ columns: `col1`, `col3`
pd.merge(df1, df2, on=['col1','col3'])
# join by: `df1.col1 == df2.index`
pd.merge(df1, df2, left_on='col1' right_index=True)
或通过索引进行连接:
df1.join(df2)
解决方案 3:
这个问题已经解决了一段时间,所有可用的选项都已经存在。然而,在这个答案中,我将尝试进一步阐明这些选项,以帮助您了解何时使用什么。
本文将讨论以下主题:
不同条件下与索引合并
基于索引的连接选项:
merge
,,join
`concat`索引合并
合并一个索引,另一个列
有效地使用命名索引来简化合并语法
基于索引的连接
总结
有几个选项,根据使用情况,有些选项比其他选项更简单。
DataFrame.merge
使用left_index
和right_index
(或left_on
和right_on
使用命名索引)
DataFrame.join
(按索引连接)
pd.concat
(按索引连接)
优点 | 缺点 | |
---|---|---|
merge | • 支持内部/左/右/完整• 支持列-列、索引-列、索引-索引连接 | • 每次只能合并两个帧 |
join | • 支持内部/左(默认)/右/完整• 可以一次连接多个 DataFrame | • 仅支持索引-索引连接 |
concat | • 专门用于一次连接多个 DataFrame • 速度非常快(连接是线性时间) | • 仅支持内部/完整(默认)连接• 仅支持索引-索引连接 |
索引到索引连接
通常,索引上的内连接看起来像这样:
left.merge(right, left_index=True, right_index=True)
其他类型的连接(左、右、外)遵循类似的语法(并且可以使用进行控制how=...
)。
值得注意的替代方案
DataFrame.join
默认为索引上的左外连接。
left.join(right, how='inner',)
如果您碰巧得到ValueError: columns overlap but no suffix specified
,则需要指定lsuffix
和rsuffix=
参数来解决这个问题。由于列名相同,因此需要区分后缀。
pd.concat
按索引进行连接,可以同时连接两个或多个 DataFrame。默认情况下,它执行完全外连接。
pd.concat([left, right], axis=1, sort=False)
有关更多信息concat
,请参阅此帖子。
索引到列的连接
要使用左索引、右列执行内连接,您将使用和DataFrame.merge
的组合。left_index=True
`right_on=...`
left.merge(right, left_index=True, right_on='key')
其他连接遵循类似的结构。请注意,只能 merge
执行索引到列的连接。您可以在多个级别/列上进行连接,前提是左侧的索引级别数等于右侧的列数。
join
并且concat
无法进行混合合并。您需要使用 设置索引作为预步骤DataFrame.set_index
。
这篇文章是我在Pandas Merging 101中工作的精简版。请点击此链接查看有关合并的更多示例和其他主题。
解决方案 4:
默认情况下:
join
是按列左连接
pd.merge
是按列内连接
pd.concat
是按行外连接
pd.concat
:
接受 Iterable 参数。因此,它不能直接接受 DataFrames(使用[df,df2]
)
DataFrame 的维度应沿轴匹配
Join
和pd.merge
:
可以采用 DataFrame 参数
解决方案 5:
一个让我困扰的愚蠢错误:由于索引不同,连接失败dtypes
。这并不明显,因为两个表都是同一张原始表的数据透视表。之后reset_index
,索引在Jupyter中看起来相同。只有在保存到 Excel 时才会显现出来……
我修复了它:df1[['key']] = df1[['key']].apply(pd.to_numeric)
希望这可以为某些人节省一个小时!
解决方案 6:
如果您想在 Pandas 中连接两个数据框,您可以简单地使用可用属性,如merge
或concatenate
。
例如,如果我有两个数据框df1
和df2
,我可以通过以下方式连接它们:
newdataframe = merge(df1, df2, left_index=True, right_index=True)
解决方案 7:
您可以尝试以下几种方法来合并/加入您的dataframe
。
merge
(默认为内连接)
df = pd.merge(df1, df2, left_index=True, right_index=True)
join
(默认左连接)
df = df1.join(df2)
concat
(默认为外连接)
df = pd.concat([df1, df2], axis=1)