我有两个数据帧,应该连接起来. 两者都是具有相同索引的多索引数据帧,但顺序不同.

所以,第一个数据帧的索引(df)看起来像:

MultiIndex([(11,  1, 1),
            (11,  1, 2),
            (11,  1, 3),
            ...
            (11, 24, 5),
            (11, 24, 6),
            (11, 24, 7)],
           names=['id_a', 'id_b', 'id_c'], length=168)

第二个看起来像:

MultiIndex([(11, 1,  1),
            (11, 2,  1),
            (11, 3,  1),
            (11, 3,  2),
            ...
            (11, 5, 23),
            (11, 6, 23),
            (11, 7, 23),
            (11, 7, 24)],
           names=['id_a', 'id_c', 'id_b'], length=168)

正如您所看到的,索引的顺序不同. 现在,通过运行pd.concat([df, df2]).index.names,我得到了以下结果:

FrozenList(['id_a', None, None])

如何重现

import pandas as pd

# create first data frame
idx = pd.MultiIndex.from_product(
    [['A1', 'A2', 'A3'], ['B1', 'B2', 'B3'], ['C1', 'C2', 'C3']],
    names=['a', 'b', 'c'])
cols = ['2010', '2020']
df = pd.DataFrame(1, idx, cols)

# Create second data frame with varying order
idx = pd.MultiIndex.from_product(
    [['A1', 'A2', 'A3'], ['C1', 'C2', 'C3'], ['B1', 'B2', 'B3']],
    names=['a', 'c', 'b'])
df2 = pd.DataFrame(2, idx, cols)

result = pd.concat([df, df2])

输出

> df
          2010  2020
a  b  c             
A1 B1 C1     1     1
      C2     1     1
      C3     1     1
   B2 C1     1     1
      C2     1     1
      C3     1     1
   B3 C1     1     1
      C2     1     1
      C3     1     1
A2 B1 C1     1     1
      C2     1     1
      C3     1     1
   B2 C1     1     1
      C2     1     1
      C3     1     1
   B3 C1     1     1
      C2     1     1
      C3     1     1
A3 B1 C1     1     1
      C2     1     1
      C3     1     1
   B2 C1     1     1
      C2     1     1
      C3     1     1
   B3 C1     1     1
      C2     1     1
      C3     1     1
> df2
          2010  2020
a  c  b             
A1 C1 B1     2     2
      B2     2     2
      B3     2     2
   C2 B1     2     2
      B2     2     2
      B3     2     2
   C3 B1     2     2
      B2     2     2
      B3     2     2
A2 C1 B1     2     2
      B2     2     2
      B3     2     2
   C2 B1     2     2
      B2     2     2
      B3     2     2
   C3 B1     2     2
      B2     2     2
      B3     2     2
A3 C1 B1     2     2
      B2     2     2
      B3     2     2
   C2 B1     2     2
      B2     2     2
      B3     2     2
   C3 B1     2     2
      B2     2     2
      B3     2     2
> result
          2010  2020
a                   
A1 B1 C1     1     1
      C2     1     1
      C3     1     1
   B2 C1     1     1
      C2     1     1
      C3     1     1
   B3 C1     1     1
      C2     1     1
      C3     1     1
A2 B1 C1     1     1
      C2     1     1
      C3     1     1
   B2 C1     1     1
      C2     1     1
      C3     1     1
   B3 C1     1     1
      C2     1     1
      C3     1     1
A3 B1 C1     1     1
      C2     1     1
      C3     1     1
   B2 C1     1     1
      C2     1     1
      C3     1     1
   B3 C1     1     1
      C2     1     1
      C3     1     1
A1 C1 B1     2     2
      B2     2     2
      B3     2     2
   C2 B1     2     2
      B2     2     2
      B3     2     2
   C3 B1     2     2
      B2     2     2
      B3     2     2
A2 C1 B1     2     2
      B2     2     2
      B3     2     2
   C2 B1     2     2
      B2     2     2
      B3     2     2
   C3 B1     2     2
      B2     2     2
      B3     2     2
A3 C1 B1     2     2
      B2     2     2
      B3     2     2
   C2 B1     2     2
      B2     2     2
      B3     2     2
   C3 B1     2     2
      B2     2     2
      B3     2     2
> result.index.names
FrozenList(['a', None, None])

索引"b"和"c"消失了.

推荐答案

如果你的水平顺序不同,你首先需要用reorder_levels重新排序:

result = pd.concat([df, df2.reorder_levels(df.index.names)])

如果您有2个以上的数据帧要连接:

dfs = [df, df2, df3, df4]

levels = dfs[0].index.names
result = pd.concat([d.reorder_levels(levels) for d in dfs])

输出:

          2010  2020
a  b  c             
A1 B1 C1     1     1
      C2     1     1
      C3     1     1
   B2 C1     1     1
      C2     1     1
      C3     1     1
...
A1 B1 C1     2     2
   B2 C1     2     2
   B3 C1     2     2
   B1 C2     2     2
...

Python相关问答推荐

使用scipy. optimate.least_squares()用可变数量的参数匹配两条曲线

Class_weight参数不影响RandomForestClassifier不平衡数据集中的结果

返回nxon矩阵的diag元素,而不使用for循环

Polars比较了两个预设-有没有方法在第一次不匹配时立即失败

对整个 pyramid 进行分组与对 pyramid 列子集进行分组

如何避免Chained when/then分配中的Mypy不兼容类型警告?

如何使用数组的最小条目拆分数组

修复mypy错误-赋值中的类型不兼容(表达式具有类型xxx,变量具有类型yyy)

如何在solve()之后获得症状上的等式的值

Streamlit应用程序中的Plotly条形图中未正确显示Y轴刻度

如何在图中标记平均点?

Django RawSQL注释字段

在嵌套span下的span中擦除信息

在matplotlib中删除子图之间的间隙_mosaic

numpy.unique如何消除重复列?

通过追加列表以极向聚合

Cython无法识别Numpy类型

如何在Python请求中组合多个适配器?

Python日志(log)模块如何在将消息发送到父日志(log)记录器之前向消息添加类实例变量

VSCode Pylance假阳性(?)对ImportError的react