如何简单地向pandas dataframe添加列级别

6qftjkof  于 2023-06-20  发布在  其他
关注(0)|答案(8)|浏览(111)

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

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

既然这个数据框架已经存在,我如何简单地将级别'C'添加到列索引中,这样我就得到了这个:

df
Out[92]: 
   A  B
   C  C
a  0  0
b  1  1
c  2  2
d  3  3
e  4  4

我看到了类似于这个python/pandas: how to combine two dataframes into one with hierarchical column index?的消息,但是这个消息是不同的数据框架,而不是在已经存在的数据框架中添加一个列级别。

nzk0hqpo

nzk0hqpo1#

正如@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
t9aqgxwy

t9aqgxwy2#

选项1

  • set_indexT *
df.T.set_index(np.repeat('C', df.shape[1]), append=True).T

选项2
*pd.concatkeysswaplevel

pd.concat([df], axis=1, keys=['C']).swaplevel(0, 1, 1)

wz1wpwve

wz1wpwve3#

一个解决方案,它添加了一个名称到新的水平,是更容易的眼睛比其他答案已经提出:

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
von4xj4u

von4xj4u4#

您可以像这样分配列:

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

或者对于未知长度的列:

>>> 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
>>>
zqry0prt

zqry0prt5#

MultiIndex的另一种方法(应用'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
ax6ht2ek

ax6ht2ek6#

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

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

这在合并具有不同列级别编号的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
798qvoo8

798qvoo87#

另一种方法,但使用元组的列表理解作为pandas.MultiIndex.from_tuples()的参数:

df.columns = pd.MultiIndex.from_tuples([(col, 'C') for col in df.columns])

df
   A  B
   C  C
a  0  0
b  1  1
c  2  2
d  3  3
e  4  4
zwghvu4y

zwghvu4y8#

我有一个专门的功能。它不那么优雅,但更灵活。优点:

  • 自动处理IndexMultiIndex
  • 可以指定名称
  • 可以一次添加多个级别
  • 选择位置(顶部或底部)

最好的问候。

def addLevel(index, value='', name=None, n=1, onTop=False):
    """Add extra dummy levels to index"""
    assert isinstance(index, (pd.MultiIndex, pd.Index))
    xar = np.array(index.tolist()).transpose()
    names = index.names if isinstance(index, pd.MultiIndex) else [index.name]
    addValues = np.full(shape=(n, xar.shape[-1]), fill_value=value)
    addName = [name] * n

    if onTop:
        names = addName + names
        xar = np.vstack([addValues, xar])
    else:
        names = names + addName
        xar = np.vstack([xar, addValues])

    return pd.MultiIndex.from_arrays(xar, names=names)
    
df = pd.DataFrame(index=list('abc'), data={'A': range(3), 'B': range(3)})
df.columns = addLevel(df.columns, value='C')
df.columns = addLevel(df.columns, value='D', name='D-name')
df.columns = addLevel(df.columns, value='E2', n=2)
df.columns = addLevel(df.columns, value='Top', name='OnTop', onTop=True)
df.columns = addLevel(df.columns, value=1, name='Number')
print(df)
## OnTop  Top   
##          A  B
##          C  C
## D-name   D  D
##         E2 E2
##         E2 E2
## Number   1  1
## a        0  0
## b        1  1
## c        2  2

相关问题