Pandas中concat函数的'levels','keys'和'names'参数分别是什么意思?

126

问题

  • 如何使用pd.concat
  • levels参数是什么意思?
  • keys参数是什么意思?
  • 有没有大量的示例来帮助解释如何使用所有参数?

Pandas的concat函数是合并工具的瑞士军刀。它适用的情况非常多。现有的文档在一些可选参数上留下了一些细节。其中包括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])

如果我要将它们连接在一起,可以使用{{concatenate}}函数。

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

使用 pandas.MultiIndex 作为我的 columns 对象,我得到了预期的结果:

        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参数文档

levels: 序列列表,默认为None。 用于构建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个回答

179

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

关于 levels 参数的具体答案将在最后给出。

pandas.concat: 失落的手册

当前文档链接

导入和定义对象

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对象的序列或映射。 如果传递了字典,则排序后的键将用作键参数,除非传递了值(见下文)。任何None对象都将被默默删除,除非它们全部为None,在这种情况下会引发ValueError。

  • 我们通常看到它与一组SeriesDataFrame对象一起使用。
  • 我将展示dict也可以非常有用。
  • 生成器也可以使用,并且在使用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

axis: {0/’index’, 1/’columns’}, default 0 要沿着连接的轴。

axis=0的两个 DataFrames (堆叠)

对于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

使用axis=1(并排)的两个DataFrame

对于值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的列扩展而来。


当沿着axis=0组合pandas.Series时,我们将得到一个pandas.Series。除非所有要合并的Series具有相同的名称,否则生成的Series的名称将为None。当打印出生成的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

使用axis=1在一侧并排组合两个(或三个)Series

当沿着axis=1组合pandas.Series时,我们需要引用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

混合使用 axis=0SeriesDataFrame (堆叠)

在沿着 axis=0 进行 SeriesDataFrame 合并时,我们将所有的 Series 转换为单列 DataFrame

请特别注意这是沿 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

使用axis=1(并排)混合SeriesDataFrame

这相当直观。当Series对象没有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,它描述了生成的合并结果应该是外连接(默认)还是内连接。

join: {‘inner’, ‘outer’}, default ‘outer’
如何处理其他轴上的索引。

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

对于 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

内部

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: 序列,默认为 None
如果传递了多个级别,则应包含元组。使用传递的键构造层次化索引,其中键作为最外层级别

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 的元组以在 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 属性。

Series axis=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
MultiIndex Series axis=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
DataFrame axis=1axis = 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
Series DataFrame axis=1

在这种情况下,当一个标量键值成为列并且同时充当DataFrameMultiIndex的第一级时,它不能作为Series对象的唯一索引级别。因此,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
keys MultiIndex 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

传递字典而不是列表

当传递一个字典时,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会获取结果的每个级别的唯一值,并将其用作结果的index.levels属性中的对象。

levels: 序列列表,默认值为None
用于构建多级索引的特定级别(唯一值)。否则,它们将从键推断出来。

如果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

列对象的层级如下:

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中的层数匹配。

names: 列表,默认为None
结果分层索引中各层级的名称

 # 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)

> 值错误:索引存在重叠值:[2]


26
对社区更有用的做法是向主要文档提交拉取请求,添加一些缺失的示例(只需几个);SO仅可搜索且不可浏览;此外,在此处放置文档链接将非常有用-绝大多数内容已经得到了充分和完整的记录。 - Jeff
6
@Jeff,我的一些成长方面进展缓慢,其中之一就是使用git。我承诺我想开始使用它。 - piRSquared
使用 pd.concat(..., levels=[lvl]).groupby(axis=1, level=0).sum()pd.concat(..., levels=[cats]).groupby(axis=1, level=0).sum() 产生了不同的结果。你知道为什么吗?文档只说 levels 应该是一个序列列表。 - unutbu
1
很好的回答,但我认为“传递字典而不是列表”部分需要使用字典而不是列表的示例。 - unutbu
1
@unutbu 我已经修复了dict的例子,谢谢。原因是lvl是一个分类索引,而cats只是一个列表。当按分类类型分组时,缺失的类别会被填充为零和适当的空值。请参见此 - piRSquared
pd.concat()join_axes部分,作者还可以提到按列名连接而不仅仅是索引,如pandas文档中所述,例如pd.concat([d1, d2], axis=0, join_axes=[d1.columns]) - Pherdindy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接