分配多索引列,同时保留索引级别值的顺序

Posted

技术标签:

【中文标题】分配多索引列,同时保留索引级别值的顺序【英文标题】:Assign multi-index column while preserving the order of index level values 【发布时间】:2020-01-05 15:11:38 【问题描述】:

我有以下具有多索引列的数据框:

df = pd.DataFrame(np.arange(6).reshape(2, 3),
    columns=pd.MultiIndex.from_tuples([('foo', 'a'), ('bar', 'a'), ('bar', 'b')]))

  foo bar   
    a   a  b
0   0   1  2
1   3   4  5

我想分配一个新列 ('foo', 'b') 以便保留索引级别 0 中值的顺序,即结果列应该是 ('foo', 'a'), ('foo', 'b'), ('bar', 'a'), ('bar', 'b')

expected = pd.DataFrame(
    [[0, 10, 1, 2], [3, 11, 4, 5]],
    columns=pd.MultiIndex.from_product([['foo', 'bar'], list('ab')]))

      foo     bar   
    a   b   a  b
0   0  10   1  2
1   3  11   4  5

以下内容会很好而且直观,但不幸的是assign 不接受位置参数:

df.assign(('foo', 'b'): [10, 11])

所以我尝试了各种选项,但新列总是附加在末尾:

# using column indexer (appends the new column to the end):
df2 = df.copy()
df2['foo', 'b'] = [10, 11]
print(df2)  # columns out of order
print(df2.sort_index(axis=1))  # order of "foo" and "bar" swapped

# using join (appends the new column to the end):
df3 = df.join(pd.DataFrame([10, 11], index=df.index,
    columns=pd.MultiIndex.from_tuples([('foo', 'b')])))
print(df3)  # columns out of order

# saving index levels beforehand doesn't help because they are sorted:
df4 = df.copy()
columns = df.columns.levels[0]  # columns out of order
df4['foo', 'b'] = [10, 11]
df4 = df4[columns]
print(df4)  # columns out of order

我可以使用[x[0] for x in df.columns],然后删除重复项(不使用set,因为应该保留顺序),然​​后使用结果来索引新数据框的列,但这种方法对于这么简单的方法来说感觉太重了任务。

我知道this question 但是那里的答案不保留列顺序。

【问题讨论】:

【参考方案1】:

那是insert

df.insert(1, ('foo', 'b'), [10, 11])
df
  foo     bar   
    a   b   a  b
0   0  10   1  2
1   3  11   4  5

【讨论】:

nice 1,.loc 以某种方式扰乱了订单 insert 似乎需要沿列的绝对位置,您只是对其进行了硬编码,但对于更复杂的设置,这可能是不可行的。所以我需要一个单独的函数来计算那个索引位置?像next(it.dropwhile(lambda x: x[1][0] == 'foo', it.dropwhile(lambda x: x[1][0] != 'foo', enumerate(df.columns))))[0] 这样的东西。看起来也很重。【参考方案2】:

最终我选择了以下内容:

    创建一级列索引器 删除重复项(使用dict 保留顺序) 用它来索引新的数据框,恢复旧的顺序

代码示例:

df['foo', 'b'] = [10, 11]
df = df[list(dict.fromkeys([x[0] for x in df.columns]))]

【讨论】:

以上是关于分配多索引列,同时保留索引级别值的顺序的主要内容,如果未能解决你的问题,请参考以下文章

使用 pandas 连接多索引列

Pandas 连接具有相同行索引的多索引列

以长格式保存具有不同级别名称的多索引列 Pandas 为 excel 格式

重命名具有任意顺序和重复列名的多索引列

如何将多索引列转换为熊猫数据框的单索引列?

Groupby 使用字典的多索引列