如何简单地将列级别添加到pandas数据帧

Ste*_*n G 37 python dataframe multi-level pandas

假设我有一个如下所示的数据框:

df = pd.DataFrame(index=list('abcde'), data={'A': range(5), 'B': range(5)})
 df
Out[92]: 
   A  B
a  0  0
b  1  1
c  2  2
d  3  3
e  4  4
Run Code Online (Sandbox Code Playgroud)

假设这个数据帧已经存在,我怎样才能简单地在列索引中添加一个"C"级别,所以我得到了这个:

 df
Out[92]: 
   A  B
   C  C
a  0  0
b  1  1
c  2  2
d  3  3
e  4  4
Run Code Online (Sandbox Code Playgroud)

我看到SO anwser就像这个python/pandas:如何将两个数据帧合并为一个具有分层列索引的数据帧?但这会使不同的数据帧不同,而不是将列级别添加到已存在的数据帧中.

-

Rom*_*ain 54

正如@StevenG本人所建议的那样,一个更好的答案:

df.columns = pd.MultiIndex.from_product([df.columns, ['C']])

print(df)
#    A  B
#    C  C
# a  0  0
# b  1  1
# c  2  2
# d  3  3
# e  4  4
Run Code Online (Sandbox Code Playgroud)

  • 当原始df已经具有多索引列名称时,您是否有任何提示,如何添加另一个级别?我尝试使用from_product()方法添加新级别,但是我收到了以下错误消息:'NotImplementedError:isnull未定义为MultiIndex'. (15认同)
  • 这太棒了,我喜欢`pd.MultiIndex.from_product([df.columns, ['C']])`,它更琐碎一些,因为您不必跟踪`df`的`len`。列`。您介意将其添加到答案中以便我可以接受吗? (2认同)
  • @LenkaVraná `pd.MultiIndex.from_product(df.columns.levels + [['C']])` (2认同)
  • 对任何人。我发现在 MultiIndex.from_product 中使用现有列索引之前将其转换为列表适用于“isna not Implemented”。`pd.MultiIndex.from_product([list(df.columns), ['C']])` (2认同)
  • 我测试的所有答案中最快(或至少是并列)的,并且最容易阅读。 (2认同)

小智 18

一个解决方案,将名称添加到新级别,并且比已经提出的其他答案更容易阅读:

df['newlevel'] = 'C'
df = df.set_index('newlevel', append=True).unstack('newlevel')

print(df)
#           A  B
# newlevel  C  C
# a         0  0
# b         1  1
# c         2  2
# d         3  3
# e         4  4
Run Code Online (Sandbox Code Playgroud)

  • 这很短,并且也适用于已经是多层的列!作为单行:`df.assign(newlevel='C').set_index('newlevel',append=True).unstack('newlevel')`。 (7认同)
  • 如果数据帧有很多行,则每行成本是不必要的 (3认同)

piR*_*red 16

选项1
set_indexT

df.T.set_index(np.repeat('C', df.shape[1]), append=True).T
Run Code Online (Sandbox Code Playgroud)

选项2
pd.concat,keysswaplevel

pd.concat([df], axis=1, keys=['C']).swaplevel(0, 1, 1)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • pd.concat([df],axis = 1,keys = ['C'])`对于多层列效果很好 (4认同)

U10*_*ard 11

您可以只分配如下列:

>>> df.columns = [df.columns, ['C', 'C']]
>>> df
   A  B
   C  C
a  0  0
b  1  1
c  2  2
d  3  3
e  4  4
>>> 
Run Code Online (Sandbox Code Playgroud)

或者对于未知长度的列:

>>> df.columns = [df.columns.get_level_values(0), np.repeat('C', df.shape[1])]
>>> df
   A  B
   C  C
a  0  0
b  1  1
c  2  2
d  3  3
e  4  4
>>> 
Run Code Online (Sandbox Code Playgroud)


小智 9

MultiIndex 的另一种方式(appanding 'E'):

df.columns = pd.MultiIndex.from_tuples(map(lambda x: (x[0], 'E', x[1]), df.columns))

   A  B
   E  E
   C  D
a  0  0
b  1  1
c  2  2
d  3  3
e  4  4
Run Code Online (Sandbox Code Playgroud)

  • 较短的版本: `df.columns = pd.MultiIndex.from_tuples([(c[0], 'E', c[1]) for c in df.columns])` (6认同)

mcs*_*ini 6

我喜欢它显式的(使用MultiIndex)和链友好的(.set_axis):

df.set_axis(pd.MultiIndex.from_product([df.columns, ['C']]), axis=1)
Run Code Online (Sandbox Code Playgroud)

当合并具有不同列级别编号的 DataFrame 时,这特别方便,其中 Pandas (1.4.2) 会引发 FutureWarning ( FutureWarning: merging between different levels is deprecated and will be removed ... ):

import pandas as pd

df1 = pd.DataFrame(index=list('abcde'), data={'A': range(5), 'B': range(5)})
df2 = pd.DataFrame(index=list('abcde'), data=range(10, 15), columns=pd.MultiIndex.from_tuples([("C", "x")]))

# df1:
   A  B
a  0  0
b  1  1

# df2:
    C
    x
a  10
b  11

# merge while giving df1 another column level:
pd.merge(df1.set_axis(pd.MultiIndex.from_product([df1.columns, ['']]), axis=1),
         df2, 
         left_index=True, right_index=True)

# result:
   A  B   C
          x
a  0  0  10
b  1  1  11


Run Code Online (Sandbox Code Playgroud)