pandas中merge()和concat()之间的差异

Win*_*mes 57 python merge join concat pandas

Pandas非常擅长处理数据分析中的各种用例.探索文档以确定执行特定任务的最佳方式可能有点令人生畏.

我目前正在努力了解pd.DataFrame.merge()和之间的本质区别pd.concat().到目前为止,这是我能说清楚的:

.merge()只能使用列(加上行索引),它在语义上适用于数据库样式的操作..concat()可以与任一轴一起使用,仅使用索引,并提供添加分层索引的选项.

顺便提一下,这允许以下冗余:两者都可以使用行索引组合两个数据帧.

至于pd.DataFrame.join()它似乎只是提供了一小部分用例的简写.merge().

有人可以评论我此时的理解是否完整和准确吗?

谢谢.

小智 49

非常高级别的差异是merge()用于根据公共列的值组合两个(或更多)数据帧(索引也可以使用,使用left_index=True和/或right_index=True),并concat()用于附加一个(或多个)数据帧一个低于另一个(或侧向,取决于该axis选项是否设置为0或1).

join()用于在索引的基础上合并2个数据帧; 而不是使用我们可以使用merge()的选项.left_index=Truejoin()

例如:

df1 = pd.DataFrame({'Key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'], 'data1': range(7)})

df1:
   Key  data1
0   b   0
1   b   1
2   a   2
3   c   3
4   a   4
5   a   5
6   b   6

df2 = pd.DataFrame({'Key': ['a', 'b', 'd'], 'data2': range(3)})

df2:
    Key data2
0   a   0
1   b   1
2   d   2

#Merge
# The 2 dataframes are merged on the basis of values in column "Key" as it is 
# a common column in 2 dataframes

pd.merge(df1, df2)

   Key data1 data2
0   b    0    1
1   b    1    1
2   b    6    1
3   a    2    0
4   a    4    0
5   a    5    0

#Concat
# df2 dataframe is appended at the bottom of df1 

pd.concat([df1, df2])

   Key data1 data2
0   b   0     NaN
1   b   1     NaN
2   a   2     NaN
3   c   3     NaN
4   a   4     NaN
5   a   5     NaN
6   b   6     NaN
0   a   Nan   0
1   b   Nan   1
2   d   Nan   2
Run Code Online (Sandbox Code Playgroud)


Jak*_* Wu 16

在高层次上:

  • .concat()简单地将多个堆叠DataFrame在一起,或者垂直堆叠,或者在索引对齐后水平缝合
  • .merge()首先对齐两个DataFrame' 选定的公共列或索引,然后从每个 ' 的对齐行中选取剩余的列DataFrame

更具体地说,.concat()

  • 是一个顶级的pandas函数
  • DataFrame 垂直或水平组合两个或多个熊猫
  • 水平组合时仅在索引上对齐
  • 当任何DataFrame包含重复索引时出错。
  • 默认为带内连接选项的外连接

并且.merge()

  • 作为顶级熊猫函数和DataFrame方法存在(从熊猫 1.0 开始)
  • DataFrame水平合并两个
  • 将调用DataFrame者的列或索引与另一个DataFrame的列或索引 对齐
  • 通过执行笛卡尔积处理连接列或索引上的重复值
  • 默认为内连接,带有左、外和右选项

请注意,在执行 时pd.merge(left, right),如果left有两行包含来自连接列或索引的相同值,则每行将与right的相应行组合,从而产生笛卡尔积。另一方面,如果.concat()用于组合列,我们需要确保其中任何一个都没有重复的索引DataFrame

实际来说:

  • 考虑.concat()混合均匀时,首先DataFrame,在考虑.merge()合并时,互补第一DataFrame
  • 如果需要垂直合并,请使用.concat(). 如果需要通过列进行水平合并,请使用.merge(),默认情况下在公共列上合并。

参考:Pandas 1.x Cookbook


小智 10

pd.concat需要一个Iterable作为其参数.因此,它不能DataFrame直接作为其论点.在连接时,还应该沿着轴匹配Dimensions DataFrame.

pd.merge可以将DataFrames作为其参数,并用于组合DataFrame具有相同列或索引的两个s,这是无法完成的,pd.concat因为它将在DataFrame中显示重复的列.

而join可用于连接DataFrame具有不同索引的两个s.

  • 我喜欢这个答案,因为它表明在连接时尺寸应该匹配.`concat`只不过是将几个数据帧粘贴在彼此的顶部/旁边.从某种意义上说它不是内容意识,它只会显示相同的列两次.而`merge`实际上*会在它们相同时合并*列. (5认同)
  • 我认为这不是真的。即使上面的答案(@Abhishek Sawant)也给出了尺寸不匹配的“concat”示例。 (4认同)

pro*_*sti 8

我目前正在尝试了解pd.DataFrame.merge()和之间的本质区别pd.concat()

好问题。主要区别:

pd.concat 适用于两个轴。

另一个区别是pd.concat只有内部默认外部连接,而pd.DataFrame.merge()具有外部内部默认连接。

第三个值得注意的其他区别是:pd.DataFrame.merge()在合并具有相同名称的列时可以选择设置列后缀,而pd.concat这是不可能的。


随着pd.concat在默认情况下,你都能够堆叠多个dataframes(行axis=0),当你设置axis=1那么你模仿的pd.DataFrame.merge()功能。

一些有用的例子pd.concat

df2=pd.concat([df]*2, ignore_index=True) #double the rows of a dataframe

df2=pd.concat([df, df.iloc[[0]]]) # add first row to the end

df3=pd.concat([df1,df2], join='inner', ignore_index=True) # concat two df's
Run Code Online (Sandbox Code Playgroud)


nul*_*ull 5

merge 和 concat 之间的主要区别在于,merge 允许您对表执行更结构化的“连接”,其中 concat 的使用范围更广且结构性更差。

合并

参考文档pd.DataFrame.mergeright作为必需参数,您可以将其视为根据一些预定义的结构化连接操作连接左表和右表。注意参数right的定义。

所需参数

  • :DataFrame 或命名系列

可选参数

  • 方式:{'left', 'right', 'outer', 'inner'} 默认为 'inner'
  • on : 标签或列表
  • left_on : 标签或列表,或类似数组
  • right_on : 标签或列表,或类似数组
  • left_index : bool,默认为False
  • right_index : bool,默认为 False
  • 排序:bool,默认为False
  • 后缀: (str, str) 的元组,默认 ('_x', '_y')
  • 复制:bool,默认为True
  • 指标: bool 或 str,默认为 False
  • 验证:str,可选

重要提示: pd.DataFrame.merge需要权限是一个pd.DataFrame或命名的pd.Series对象。

输出

  • 返回:数据帧

此外,如果我们检查熊猫合并操作的文档字符串如下:

使用列作为键或其行索引在两个 DataFrame 或 Series 对象之间执行数据库 (SQL) 合并操作

康卡特

请参阅文件pd.concat,首先要注意的参数中指定的任何的表,data_frame,系列,矩阵等,但OBJ文件来代替。也就是说,你可以传递许多“数据容器”,它们被定义为:

Iterable[FrameOrSeriesUnion], Mapping[Optional[Hashable], FrameOrSeriesUnion]

所需参数

  • objs : Series 或 DataFrame 对象的序列或映射

可选参数

  • :{0/'index', 1/'columns'},默认为 0
  • 加入: {'inner', 'outer'}, 默认为 'outer'
  • ignore_index : bool,默认为 False
  • :序列,默认无
  • levels : 序列列表,默认无
  • 名称:列表,默认无
  • verify_integrity : bool,默认为 False
  • 排序:bool,默认为False
  • 复制:bool,默认为True

输出

  • 返回:对象,对象类型

例子

代码

import pandas as pd

v1 = pd.Series([1, 5, 9, 13])
v2 = pd.Series([10, 100, 1000, 10000])
v3 = pd.Series([0, 1, 2, 3])

df_left = pd.DataFrame({
    "v1": v1,
    "v2": v2,
    "v3": v3
    })
df_right = pd.DataFrame({
    "v4": [5, 5, 5, 5],
    "v5": [3, 2, 1, 0]
    })


df_concat = pd.concat([v1, v2, v3])

# Performing operations on default

merge_result = df_left.merge(df_right, left_index=True, right_index=True)
concat_result = pd.concat([df_left, df_right], sort=False)
print(merge_result)
print('='*20)
print(concat_result)
Run Code Online (Sandbox Code Playgroud)

代码输出

   v1     v2  v3  v4  v5
0   1     10   0   5   3
1   5    100   1   5   2
2   9   1000   2   5   1
3  13  10000   3   5   0
====================
     v1       v2   v3   v4   v5
0   1.0     10.0  0.0  NaN  NaN
1   5.0    100.0  1.0  NaN  NaN
2   9.0   1000.0  2.0  NaN  NaN
3  13.0  10000.0  3.0  NaN  NaN
0   NaN      NaN  NaN  5.0  3.0
1   NaN      NaN  NaN  5.0  2.0
2   NaN      NaN  NaN  5.0  1.0
Run Code Online (Sandbox Code Playgroud)

但是,您可以通过更改参数来使用 concat 实现第一个输出(合并)

concat_result = pd.concat([df_left, df_right], sort=False, axis=1)
Run Code Online (Sandbox Code Playgroud)

观察以下行为,

concat_result = pd.concat([df_left, df_right, df_left, df_right], sort=False)
Run Code Online (Sandbox Code Playgroud)

输出;

     v1       v2   v3   v4   v5
0   1.0     10.0  0.0  NaN  NaN
1   5.0    100.0  1.0  NaN  NaN
2   9.0   1000.0  2.0  NaN  NaN
3  13.0  10000.0  3.0  NaN  NaN
0   NaN      NaN  NaN  5.0  3.0
1   NaN      NaN  NaN  5.0  2.0
2   NaN      NaN  NaN  5.0  1.0
3   NaN      NaN  NaN  5.0  0.0
0   1.0     10.0  0.0  NaN  NaN
1   5.0    100.0  1.0  NaN  NaN
2   9.0   1000.0  2.0  NaN  NaN
3  13.0  10000.0  3.0  NaN  NaN
0   NaN      NaN  NaN  5.0  3.0
1   NaN      NaN  NaN  5.0  2.0
2   NaN      NaN  NaN  5.0  1.0
3   NaN      NaN  NaN  5.0  0.0
Run Code Online (Sandbox Code Playgroud)

,您不能使用合并执行类似的操作,因为它只允许单个 DataFrame 或命名系列。

merge_result = df_left.merge([df_right, df_left, df_right], left_index=True, right_index=True)
Run Code Online (Sandbox Code Playgroud)

输出;

TypeError: Can only merge Series or DataFrame objects, a <class 'list'> was passed
Run Code Online (Sandbox Code Playgroud)

结论

您可能已经注意到,“合并”和“连接”之间的输入和输出可能不同。

正如我在开头提到的,第一个(主要)区别是“合并”对一组受限制的对象和参数执行更结构化的连接,而“连接”对更广泛的集合执行不太严格/更广泛的连接对象和参数。

总而言之,merge 对更改/(输入)的容忍度较低,而“concat”对更改/(输入)更松散/不那么敏感。您可以通过使用“concat”来实现“合并”,但反过来并不总是正确的。

“合并”操作使用数据框列(或pd.Series对象名称)或行索引,并且由于它仅使用这些实体,因此它执行数据框或系列的水平合并,因此不应用垂直操作。

如果你想看更多,你可以深入研究一下源代码;