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

时间:2019-09-02 15:16:42

标签: python python-3.x pandas

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

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,但是那里的答案并没有保留列的顺序。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

最终我遵循以下条件:

  1. 创建一级列索引器
  2. 删除重复项(使用dict保留顺序)
  3. 使用它索引到新数据框中,恢复旧顺序

代码示例:

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