Панды.Копировать уровень multiIndex - PullRequest
0 голосов
/ 02 декабря 2018

У меня есть DataFrame с многоиндексированными столбцами:

df = pd.DataFrame(np.arange(12).reshape(3,-1))
df.columns = [['A', 'A', 'B', 'B'], [0, 1, 0, 1]]
print(df)

Это выглядит так:

   A      B    
   0  1   0   1
0  0  1   2   3
1  4  5   6   7
2  8  9  10  11

Я хочу сделать что-то вроде df['C'] = df['B'], чтобы получить:

    A       B       C    
    0   1   0   1   0   1
0   0   1   2   3   2   3
1   6   7   8   9   8   9
2  12  13  14  15  14  15

Я получаю ValueError: Wrong number of items passed 2, placement implies 1.

Я также попытался df.loc[:, slice('C', None)] = df['B'] без удачи.

На самом деле мой случай немного сложнее: у меня есть еще один уровень вмультииндекс (L0 I) и я хочу скопировать df['L0 I', 'B'] в df['L0 II', 'B'] (L0 II не существует).

1 Ответ

0 голосов
/ 02 декабря 2018

Вы можете извлечь столбец и создать MultiIndex в столбце:

df1 = df['B']
df1.columns = [['C'] * len(df1.columns), df1.columns]
print (df1)
    C    
    0   1
0   2   3
1   6   7
2  10  11

Или выбрать по срезу и rename первый уровень:

df1 = df.loc[:, slice('B', None)].rename(columns={'B':'C'}, level=0)
print (df1)
    C    
    0   1
0   2   3
1   6   7
2  10  11

И затем join или concat вместе:

df = df.join(df1)
#alternative
#df = pd.concat([df,df1], axis=1)
print (df)
   A      B       C    
   0  1   0   1   0   1
0  0  1   2   3   2   3
1  4  5   6   7   6   7
2  8  9  10  11  10  11

Другое работающее здесь решение - использовать DataFrame.stack, дубликат столбца с DataFrame.assign и измените форму на DataFrame.unstack:

df1 = df.stack().assign(C = lambda x: x['B']).unstack()
print (df1)
   A      B       C    
   0  1   0   1   0   1
0  0  1   2   3   2   3
1  4  5   6   7   6   7
2  8  9  10  11  10  11
...