Pandas 的 concat 函数中的“级别”、“键”和名称参数是啥?

Posted

技术标签:

【中文标题】Pandas 的 concat 函数中的“级别”、“键”和名称参数是啥?【英文标题】:What are the 'levels', 'keys', and names arguments for in Pandas' concat function?Pandas 的 concat 函数中的“级别”、“键”和名称参数是什么? 【发布时间】:2018-09-12 05:12:32 【问题描述】:

问题

如何使用pd.concatlevels 参数的用途是什么? keys 参数的用途是什么? 是否有大量示例可以帮助解释如何使用所有参数?

Pandas 的 concat 函数是合并实用程序的 Swiss Army knife。它有用的各种情况很多。现有的文档遗漏了一些关于一些可选参数的细节。其中包括levelskeys 参数。我着手弄清楚这些论点的作用。

我将提出一个问题,作为通往pd.concat 多个方面的门户。

考虑数据框d1d2d3

import pandas as pd

d1 = pd.DataFrame(dict(A=.1, B=.2, C=.3), [2, 3])
d2 = pd.DataFrame(dict(B=.4, C=.5, D=.6), [1, 2])
d3 = pd.DataFrame(dict(A=.7, B=.8, D=.9), [1, 3])

如果我将这些连接在一起

pd.concat([d1, d2, d3], keys=['d1', 'd2', 'd3'])

我的columns 对象得到了pandas.MultiIndex 的预期结果:

        A    B    C    D
d1 2  0.1  0.2  0.3  NaN
   3  0.1  0.2  0.3  NaN
d2 1  NaN  0.4  0.5  0.6
   2  NaN  0.4  0.5  0.6
d3 1  0.7  0.8  NaN  0.9
   3  0.7  0.8  NaN  0.9

但是,我想使用levels argument documentation:

levels:序列列表,默认无。 用于构造 MultiIndex 的特定级别(唯一值)。否则,它们将从键中推断出来。

所以我通过了

pd.concat([d1, d2, d3], keys=['d1', 'd2', 'd3'], levels=[['d1', 'd2']])

并获得KeyError

ValueError: Key d3 not in level Index(['d1', 'd2'], dtype='object')

这是有道理的。我通过的级别不足以描述按键指示的必要级别。如果我没有像上面所做的那样通过任何东西,那么会推断出级别(如文档中所述)。但是我还能如何使用这个论点来获得更好的效果呢?

如果我尝试这样做:

pd.concat([d1, d2, d3], keys=['d1', 'd2', 'd3'], levels=[['d1', 'd2', 'd3']])

我得到了和上面一样的结果。但是当我在关卡中再添加一个值时,

df = pd.concat([d1, d2, d3], keys=['d1', 'd2', 'd3'], levels=[['d1', 'd2', 'd3', 'd4']])

我最终得到了相同的数据框,但生成的 MultiIndex 有一个未使用的级别。

df.index.levels[0]

Index(['d1', 'd2', 'd3', 'd4'], dtype='object')

那么level 参数的意义何在?我应该以不同的方式使用keys 吗?

我正在使用 Python 3.6 和 Pandas 0.22。

【问题讨论】:

【参考方案1】:

在自己回答这个问题的过程中,我学到了很多东西,我想整理一个例子目录和一些解释。

levels 论点的具体答案将在最后。

pandas.concat: 缺失的手册

Link To Current Documentation

导入和定义对象

import pandas as pd

d1 = pd.DataFrame(dict(A=.1, B=.2, C=.3), index=[2, 3])
d2 = pd.DataFrame(dict(B=.4, C=.5, D=.6), index=[1, 2])
d3 = pd.DataFrame(dict(A=.7, B=.8, D=.9), index=[1, 3])

s1 = pd.Series([1, 2], index=[2, 3])
s2 = pd.Series([3, 4], index=[1, 2])
s3 = pd.Series([5, 6], index=[1, 3])

参数

objs

我们遇到的第一个参数是objs

objs:Series、DataFrame 或 Panel 对象的序列或映射 如果传递了 dict,则排序后的键将用作 keys 参数,除非它被传递,在这种情况下将选择值(见下文)。任何 None 对象都将被静默删除,除非它们都是 None 在这种情况下会引发 ValueError

我们通常会看到它与SeriesDataFrame 对象列表一起使用。 我将证明dict 也非常有用。 也可以使用生成器,并且在使用map 时很有用,如map(f, list_of_df)

现在,我们将坚持使用上面定义的一些DataFrameSeries 对象的列表。 稍后我将展示如何利用字典来提供非常有用的MultiIndex 结果。

pd.concat([d1, d2])

     A    B    C    D
2  0.1  0.2  0.3  NaN
3  0.1  0.2  0.3  NaN
1  NaN  0.4  0.5  0.6
2  NaN  0.4  0.5  0.6

axis

我们遇到的第二个参数是axis,其默认值为0

:0/'index', 1/'columns',默认 0 要连接的轴。

两个DataFrames 和axis=0(堆叠)

对于0index 的值,我们的意思是:“沿列对齐并添加到索引中”。

如上所示,我们使用axis=0,因为0是默认值,我们看到d2的索引扩展了d1的索引,尽管2的值有重叠:

pd.concat([d1, d2], axis=0)

     A    B    C    D
2  0.1  0.2  0.3  NaN
3  0.1  0.2  0.3  NaN
1  NaN  0.4  0.5  0.6
2  NaN  0.4  0.5  0.6

两个DataFrames 和axis=1(并排)

对于值1columns,我们的意思是:“沿索引对齐并添加到列中”,

pd.concat([d1, d2], axis=1)

     A    B    C    B    C    D
1  NaN  NaN  NaN  0.4  0.5  0.6
2  0.1  0.2  0.3  0.4  0.5  0.6
3  0.1  0.2  0.3  NaN  NaN  NaN

我们可以看到生成的索引是索引的并集,生成的列是d1 的列与d2 的列的扩展。

两个(或三个)Seriesaxis=0(堆叠)

当结合pandas.Seriesaxis=0 时,我们得到一个pandas.Series。生成的 Series 的名称将是 None,除非所有 Series 组合在一起具有相同的名称。当我们打印出结果Series 时,请注意'Name: A'。当它不存在时,我们可以假设 Series 名称是 None

               |                       |                        |  pd.concat(
               |  pd.concat(           |  pd.concat(            |      [s1.rename('A'),
 pd.concat(    |      [s1.rename('A'), |      [s1.rename('A'),  |       s2.rename('B'),
     [s1, s2]) |       s2])            |       s2.rename('A')]) |       s3.rename('A')])
-------------- | --------------------- | ---------------------- | ----------------------
2    1         | 2    1                | 2    1                 | 2    1
3    2         | 3    2                | 3    2                 | 3    2
1    3         | 1    3                | 1    3                 | 1    3
2    4         | 2    4                | 2    4                 | 2    4
dtype: int64   | dtype: int64          | Name: A, dtype: int64  | 1    5
               |                       |                        | 3    6
               |                       |                        | dtype: int64

两个(或三个)Seriesaxis=1(并排)

当将pandas.Seriesaxis=1 组合在一起时,我们引用的是name 属性,以便在生成的pandas.DataFrame 中推断列名。

                       |                       |  pd.concat(
                       |  pd.concat(           |      [s1.rename('X'),
 pd.concat(            |      [s1.rename('X'), |       s2.rename('Y'),
     [s1, s2], axis=1) |       s2], axis=1)    |       s3.rename('Z')], axis=1)
---------------------- | --------------------- | ------------------------------
     0    1            |      X    0           |      X    Y    Z
1  NaN  3.0            | 1  NaN  3.0           | 1  NaN  3.0  5.0
2  1.0  4.0            | 2  1.0  4.0           | 2  1.0  4.0  NaN
3  2.0  NaN            | 3  2.0  NaN           | 3  2.0  NaN  6.0

SeriesDataFrameaxis=0 混合(堆叠)

在将SeriesDataFrameaxis=0 串联时,我们将所有Series 转换为单列DataFrames。

请特别注意,这是axis=0 的串联;这意味着在对齐列的同时扩展索引(行)。在下面的示例中,我们看到索引变为[2, 3, 2, 3],这是一个不加选择的索引附加。除非我强制使用 to_frame 的参数命名 Series 列,否则列不会重叠:

 pd.concat(               |
     [s1.to_frame(), d1]) |  pd.concat([s1, d1])
------------------------- | ---------------------
     0    A    B    C     |      0    A    B    C
2  1.0  NaN  NaN  NaN     | 2  1.0  NaN  NaN  NaN
3  2.0  NaN  NaN  NaN     | 3  2.0  NaN  NaN  NaN
2  NaN  0.1  0.2  0.3     | 2  NaN  0.1  0.2  0.3
3  NaN  0.1  0.2  0.3     | 3  NaN  0.1  0.2  0.3

您可以看到pd.concat([s1, d1]) 的结果与我自己执行to_frame 的结果相同。

但是,我可以使用to_frame 的参数来控制结果列的名称。使用rename 方法重命名Series控制生成的DataFrame 中的列名。

 # Effectively renames       |                            |
 # `s1` but does not align   |  # Does not rename.  So    |  # Renames to something
 # with columns in `d1`      |  # Pandas defaults to `0`  |  # that does align with `d1`
 pd.concat(                  |  pd.concat(                |  pd.concat(
     [s1.to_frame('X'), d1]) |      [s1.rename('X'), d1]) |      [s1.to_frame('B'), d1])
---------------------------- | -------------------------- | ----------------------------
     A    B    C    X        |      0    A    B    C      |      A    B    C
2  NaN  NaN  NaN  1.0        | 2  1.0  NaN  NaN  NaN      | 2  NaN  1.0  NaN
3  NaN  NaN  NaN  2.0        | 3  2.0  NaN  NaN  NaN      | 3  NaN  2.0  NaN
2  0.1  0.2  0.3  NaN        | 2  NaN  0.1  0.2  0.3      | 2  0.1  0.2  0.3
3  0.1  0.2  0.3  NaN        | 3  NaN  0.1  0.2  0.3      | 3  0.1  0.2  0.3

SeriesDataFrameaxis=1 混合在一起(并排)

这是相当直观的。当name 属性不可用时,Series 列名默认为此类Series 对象的枚举。

                    |  pd.concat(
 pd.concat(         |      [s1.rename('X'),
     [s1, d1],      |       s2, s3, d1],
     axis=1)        |      axis=1)
------------------- | -------------------------------
   0    A    B    C |      X    0    1    A    B    C
2  1  0.1  0.2  0.3 | 1  NaN  3.0  5.0  NaN  NaN  NaN
3  2  0.1  0.2  0.3 | 2  1.0  4.0  NaN  0.1  0.2  0.3
                    | 3  2.0  NaN  6.0  0.1  0.2  0.3

join

第三个参数是 join,它描述了生成的合并应该是外部合并(默认)还是内部合并。

加入:‘inner’, ‘outer’,默认‘outer’ 如何处理其他轴上的索引。

事实证明,没有leftright 选项,因为pd.concat 可以处理两个以上要合并的对象。

对于d1d2,选项如下所示:

outer

pd.concat([d1, d2], axis=1, join='outer')

     A    B    C    B    C    D
1  NaN  NaN  NaN  0.4  0.5  0.6
2  0.1  0.2  0.3  0.4  0.5  0.6
3  0.1  0.2  0.3  NaN  NaN  NaN

inner

pd.concat([d1, d2], axis=1, join='inner')

     A    B    C    B    C    D
2  0.1  0.2  0.3  0.4  0.5  0.6

join_axes

第四个参数允许我们进行left 合并等等。

join_axes:索引对象列表 用于其他 n - 1 个轴的特定索引,而不是执行内部/外部集逻辑。

左合并

pd.concat([d1, d2, d3], axis=1, join_axes=[d1.index])

     A    B    C    B    C    D    A    B    D
2  0.1  0.2  0.3  0.4  0.5  0.6  NaN  NaN  NaN
3  0.1  0.2  0.3  NaN  NaN  NaN  0.7  0.8  0.9

右合并

pd.concat([d1, d2, d3], axis=1, join_axes=[d3.index])

     A    B    C    B    C    D    A    B    D
1  NaN  NaN  NaN  0.4  0.5  0.6  0.7  0.8  0.9
3  0.1  0.2  0.3  NaN  NaN  NaN  0.7  0.8  0.9

ignore_index

ignore_index:布尔值,默认为 False 如果为 True,则不要沿连接轴使用索引值。生成的轴将标记为 0, ..., n - 1。如果您在连接轴没有有意义的索引信息的情况下连接对象,这将很有用。请注意,其他轴上的索引值在连接中仍然受到尊重。

就像当我将d1 堆叠在d2 之上时,如果我不关心索引值,我可以重置它们或忽略它们。

                      |  pd.concat(             |  pd.concat(
                      |      [d1, d2],          |      [d1, d2]
 pd.concat([d1, d2])  |      ignore_index=True) |  ).reset_index(drop=True)
--------------------- | ----------------------- | -------------------------
     A    B    C    D |      A    B    C    D   |      A    B    C    D
2  0.1  0.2  0.3  NaN | 0  0.1  0.2  0.3  NaN   | 0  0.1  0.2  0.3  NaN
3  0.1  0.2  0.3  NaN | 1  0.1  0.2  0.3  NaN   | 1  0.1  0.2  0.3  NaN
1  NaN  0.4  0.5  0.6 | 2  NaN  0.4  0.5  0.6   | 2  NaN  0.4  0.5  0.6
2  NaN  0.4  0.5  0.6 | 3  NaN  0.4  0.5  0.6   | 3  NaN  0.4  0.5  0.6

而当使用axis=1:

                                   |     pd.concat(
                                   |         [d1, d2], axis=1,
 pd.concat([d1, d2], axis=1)       |         ignore_index=True)
-------------------------------    |    -------------------------------
     A    B    C    B    C    D    |         0    1    2    3    4    5
1  NaN  NaN  NaN  0.4  0.5  0.6    |    1  NaN  NaN  NaN  0.4  0.5  0.6
2  0.1  0.2  0.3  0.4  0.5  0.6    |    2  0.1  0.2  0.3  0.4  0.5  0.6
3  0.1  0.2  0.3  NaN  NaN  NaN    |    3  0.1  0.2  0.3  NaN  NaN  NaN

keys

我们可以传递一个标量值或元组列表,以便将元组或标量值分配给相应的 MultiIndex。传递的列表的长度必须与要连接的项目数的长度相同。

keys:序列,默认无 如果通过了多个级别,则应包含元组。以传递的键为最外层构造层次索引

axis=0

沿axis=0 连接Series 对象时(扩展索引)。

那些键,成为索引属性中MultiIndex对象的新初始级别。

 #           length 3             length 3           #         length 2        length 2
 #          /--------\         /-----------\         #          /----\         /------\
 pd.concat([s1, s2, s3], keys=['A', 'B', 'C'])       pd.concat([s1, s2], keys=['A', 'B'])
----------------------------------------------      -------------------------------------
A  2    1                                           A  2    1
   3    2                                              3    2
B  1    3                                           B  1    3
   2    4                                              2    4
C  1    5                                           dtype: int64
   3    6
dtype: int64

但是,我们可以在keys 参数中使用更多的标量值来创建更深的MultiIndex。在这里,我们将长度为 2 的 tuples 传递给 MultiIndex 的两个新级别:

 pd.concat(
     [s1, s2, s3],
     keys=[('A', 'X'), ('A', 'Y'), ('B', 'X')])
-----------------------------------------------
A  X  2    1
      3    2
   Y  1    3
      2    4
B  X  1    5
      3    6
dtype: int64

axis=1

沿列延伸时有点不同。当我们使用axis=0(见上文)时,除了现有索引之外,我们的keys 还充当MultiIndex 级别。对于axis=1,我们指的是Series 对象没有的轴,即columns 属性。

两个Seriesaxis=1 的变体

请注意,只要没有传递 keys,命名 s1s2 就很重要,但如果传递了 keys,它将被覆盖。

               |                       |                        |  pd.concat(
               |  pd.concat(           |  pd.concat(            |      [s1.rename('U'),
 pd.concat(    |      [s1, s2],        |      [s1.rename('U'),  |       s2.rename('V')],
     [s1, s2], |      axis=1,          |       s2.rename('V')], |       axis=1,
     axis=1)   |      keys=['X', 'Y']) |       axis=1)          |       keys=['X', 'Y'])
-------------- | --------------------- | ---------------------- | ----------------------
     0    1    |      X    Y           |      U    V            |      X    Y
1  NaN  3.0    | 1  NaN  3.0           | 1  NaN  3.0            | 1  NaN  3.0
2  1.0  4.0    | 2  1.0  4.0           | 2  1.0  4.0            | 2  1.0  4.0
3  2.0  NaN    | 3  2.0  NaN           | 3  2.0  NaN            | 3  2.0  NaN
MultiIndexSeriesaxis=1
 pd.concat(
     [s1, s2],
     axis=1,
     keys=[('W', 'X'), ('W', 'Y')])
-----------------------------------
     W
     X    Y
1  NaN  3.0
2  1.0  4.0
3  2.0  NaN
两个DataFrameaxis=1

axis=0 示例一样,keys 将级别添加到MultiIndex,但这次添加到存储在columns 属性中的对象。

 pd.concat(                     |  pd.concat(
     [d1, d2],                  |      [d1, d2],
     axis=1,                    |      axis=1,
     keys=['X', 'Y'])           |      keys=[('First', 'X'), ('Second', 'X')])
------------------------------- | --------------------------------------------
     X              Y           |   First           Second
     A    B    C    B    C    D |       X                X
1  NaN  NaN  NaN  0.4  0.5  0.6 |       A    B    C      B    C    D
2  0.1  0.2  0.3  0.4  0.5  0.6 | 1   NaN  NaN  NaN    0.4  0.5  0.6
3  0.1  0.2  0.3  NaN  NaN  NaN | 2   0.1  0.2  0.3    0.4  0.5  0.6
                                | 3   0.1  0.2  0.3    NaN  NaN  NaN
SeriesDataFrameaxis=1

这很棘手。在这种情况下,标量键值不能作为Series 对象在成为列时的唯一索引级别,同时也作为DataFrameMultiIndex 的第一级别。所以 Pandas 将再次使用Series 对象的name 属性作为列名的来源。

 pd.concat(           |  pd.concat(
     [s1, d1],        |      [s1.rename('Z'), d1],
     axis=1,          |      axis=1,
     keys=['X', 'Y']) |      keys=['X', 'Y'])
--------------------- | --------------------------
   X    Y             |    X    Y
   0    A    B    C   |    Z    A    B    C
2  1  0.1  0.2  0.3   | 2  1  0.1  0.2  0.3
3  2  0.1  0.2  0.3   | 3  2  0.1  0.2  0.3
keysMultiIndex 推理的局限性。

Pandas 似乎只能从 Series 名称推断列名称,但在对具有不同列级别数的数据帧进行类似连接时,它不会填补空白。

d1_ = pd.concat(
    [d1], axis=1,
    keys=['One'])
d1_

   One
     A    B    C
2  0.1  0.2  0.3
3  0.1  0.2  0.3

然后将其与列对象中只有一个级别的另一个数据框连接起来,Pandas 将拒绝尝试制作MultiIndex 对象的元组,并将所有数据框组合成一个级别的对象、标量和元组。

pd.concat([d1_, d2], axis=1)

   (One, A)  (One, B)  (One, C)    B    C    D
1       NaN       NaN       NaN  0.4  0.5  0.6
2       0.1       0.2       0.3  0.4  0.5  0.6
3       0.1       0.2       0.3  NaN  NaN  NaN

传递 dict 而不是 list

传递字典时,pandas.concat 将使用字典中的键作为keys 参数。

 # axis=0               |  # axis=1
 pd.concat(             |  pd.concat(
     0: d1, 1: d2)    |      0: d1, 1: d2, axis=1)
----------------------- | -------------------------------
       A    B    C    D |      0              1
0 2  0.1  0.2  0.3  NaN |      A    B    C    B    C    D
  3  0.1  0.2  0.3  NaN | 1  NaN  NaN  NaN  0.4  0.5  0.6
1 1  NaN  0.4  0.5  0.6 | 2  0.1  0.2  0.3  0.4  0.5  0.6
  2  NaN  0.4  0.5  0.6 | 3  0.1  0.2  0.3  NaN  NaN  NaN

levels

这与keys 参数一起使用。当levels 保留其默认值None 时,Pandas 将采用生成的MultiIndex 的每个级别的唯一值并将其用作生成的index.levels 属性中使用的对象。

levels:序列列表,默认无 用于构造 MultiIndex 的特定级别(唯一值)。否则它们将从键中推断出来。

如果 Pandas 已经推断出这些级别应该是什么,那么我们自己指定它有什么好处?我将展示一个示例,并由您自己思考为什么这可能有用的其他原因。

示例

根据文档,levels 参数是一个序列列表。这意味着我们可以使用另一个pandas.Index 作为这些序列之一。

考虑数据框df,它是d1d2d3的串联:

df = pd.concat(
    [d1, d2, d3], axis=1,
    keys=['First', 'Second', 'Fourth'])

df

  First           Second           Fourth
      A    B    C      B    C    D      A    B    D
1   NaN  NaN  NaN    0.4  0.5  0.6    0.7  0.8  0.9
2   0.1  0.2  0.3    0.4  0.5  0.6    NaN  NaN  NaN
3   0.1  0.2  0.3    NaN  NaN  NaN    0.7  0.8  0.9

columns 对象的级别是:

print(df, *df.columns.levels, sep='\n')

Index(['First', 'Second', 'Fourth'], dtype='object')
Index(['A', 'B', 'C', 'D'], dtype='object')

如果我们在groupby 中使用sum,我们会得到:

df.groupby(axis=1, level=0).sum()

   First  Fourth  Second
1    0.0     2.4     1.5
2    0.6     0.0     1.5
3    0.6     2.4     0.0

但是,如果不是['First', 'Second', 'Fourth'] 而是缺少另一个名为ThirdFifth 的类别怎么办?我希望它们包含在groupby 聚合的结果中?如果我们有pandas.CategoricalIndex,我们可以做到这一点。我们可以使用 levels 参数提前指定。

因此,让我们将df 定义为:

cats = ['First', 'Second', 'Third', 'Fourth', 'Fifth']
lvl = pd.CategoricalIndex(cats, categories=cats, ordered=True)

df = pd.concat(
    [d1, d2, d3], axis=1,
    keys=['First', 'Second', 'Fourth'],
    levels=[lvl]
)

df

   First  Fourth  Second
1    0.0     2.4     1.5
2    0.6     0.0     1.5
3    0.6     2.4     0.0

但是columns对象的第一层是:

df.columns.levels[0]

CategoricalIndex(
    ['First', 'Second', 'Third', 'Fourth', 'Fifth'],
    categories=['First', 'Second', 'Third', 'Fourth', 'Fifth'],
    ordered=True, dtype='category')

我们的groupby 总和看起来像:

df.groupby(axis=1, level=0).sum()

   First  Second  Third  Fourth  Fifth
1    0.0     1.5    0.0     2.4    0.0
2    0.6     1.5    0.0     0.0    0.0
3    0.6     0.0    0.0     2.4    0.0

names

这用于命名生成的MultiIndex 的级别。 names 列表的长度应与生成的 MultiIndex 中的级别数匹配。

名称:列表,默认无 生成的分层索引中的级别名称

 # axis=0                     |  # axis=1
 pd.concat(                   |  pd.concat(
     [d1, d2],                |      [d1, d2],
     keys=[0, 1],             |      axis=1, keys=[0, 1],
     names=['lvl0', 'lvl1'])  |      names=['lvl0', 'lvl1'])
----------------------------- | ----------------------------------
             A    B    C    D | lvl0    0              1
lvl0 lvl1                     | lvl1    A    B    C    B    C    D
0    2     0.1  0.2  0.3  NaN | 1     NaN  NaN  NaN  0.4  0.5  0.6
     3     0.1  0.2  0.3  NaN | 2     0.1  0.2  0.3  0.4  0.5  0.6
1    1     NaN  0.4  0.5  0.6 | 3     0.1  0.2  0.3  NaN  NaN  NaN
     2     NaN  0.4  0.5  0.6 |

verify_integrity

自解释文档

verify_integrity:布尔值,默认为 False 检查新的连接轴是否包含重复项。相对于实际的数据连接,这可能非常昂贵。

因为连接d1d2 得到的索引不是唯一的,所以完整性检查会失败。

pd.concat([d1, d2])

     A    B    C    D
2  0.1  0.2  0.3  NaN
3  0.1  0.2  0.3  NaN
1  NaN  0.4  0.5  0.6
2  NaN  0.4  0.5  0.6

pd.concat([d1, d2], verify_integrity=True)

> ValueError:索引具有重叠值:[2]

【讨论】:

对社区来说,简单地做一个拉取请求来添加一些缺失的例子(只是几个)到主文档中真的会更有用; SO 只能搜索,不能浏览;在这里进一步放置文档链接会很有用 - 其中绝大多数已经很好并且完全记录在案 @Jeff 我的成长有些缓慢。使用 git 就是其中之一。我保证这就是我想要开始做的事情。 使用pd.concat(..., levels=[lvl]).groupby(axis=1, level=0).sum() 产生的结果与pd.concat(..., levels=[cats]).groupby(axis=1, level=0).sum() 不同。你知道为什么吗?文档只说levels 应该是一个序列列表。 很好的答案,但我认为Passing a dict instead of a list 部分需要一个使用字典而不是列表的示例。 @unutbu 我已经修复了dict 示例,谢谢。原因是lvl 是一个分类索引,cats 只是一个列表。当按分类类型分组时,缺失的类别会在适当的地方用零和空值填充。 See this

以上是关于Pandas 的 concat 函数中的“级别”、“键”和名称参数是啥?的主要内容,如果未能解决你的问题,请参考以下文章

pandas 合并数据函数merge join concat combine_first 区分

pandas数据合并之append与concat

pandas的连接函数concat()函数

Pandas 中的 Concat 2 列 - AttributeError:“DataFrame”对象没有属性“concat”

pandas的concat方法

pandas的拼接操作