Метод установки новых столбцов Multiindex из другого фрейма данных

Учитывая DataFrame (d) со столбцами MultiIndex, я хотел бы установить другой DataFrame (d2) в качестве одного из «многостолбцов», чтобы верхний уровень имел некоторую метку, а метки второго уровня соответствовали оригиналу:

nr.seed(0)
abc = ['a', 'b', 'c']
mi = pd.MultiIndex.from_product([['A'], abc])
d = DataFrame(np.random.randint(0, 10, (4, 3)), columns=mi)
d
   A      
   a  b  c
0  5  0  3
1  3  7  9
2  3  5  2
3  4  7  6

d2 = DataFrame(np.random.randint(0, 10, (4, 3)), columns=abc)
d2
   a  b  c
0  8  8  1
1  6  7  7
2  8  1  5
3  9  8  9

Если возможно, я хотел бы присоединиться к ним, используя один встроенный метод, который выполняет следующий цикл forloop:

for c2 in d2:
    d['B', c2] = d2[c2]
d
   A        B      
   a  b  c  a  b  c
0  5  0  3  8  8  1
1  3  7  9  6  7  7
2  3  5  2  8  1  5
3  4  7  6  9  8  9

Для DataFrame с одноуровневым столбцом:

d3 = d.copy()
d3.columns = d3.columns.droplevel(0)
d3 = d3.rename(columns=dict(zip('abc', 'def')))
d3
   d  e  f
0  5  0  3
1  3  7  9
2  3  5  2
3  4  7  6

Я могу сделать следующее:

d3[d2.columns] = d2
d3
   d  e  f  a  b  c
0  5  0  3  8  8  1
1  3  7  9  6  7  7
2  3  5  2  8  1  5
3  4  7  6  9  8  9

Но когда я пробую это с MultiIndexed DataFrame, я получаю ошибки:

d['B', tuple(d2.columns)] = d2
=> ValueError: Wrong number of items passed 3, placement implies 1
d['B'][tuple(d2.columns)] = d2
=> KeyError: 'B'

Есть ли встроенный метод для этого? (В основном делайте это для нескольких столбцов одновременно) .


person beardc    schedule 27.05.2016    source источник


Ответы (1)


ОБНОВЛЕНИЕ:

def add_multicolumn(df, df2, new_col_name):
    tmp = df2.copy()    # make copy, otherwise df2 will be changed !!!
    tmp.columns = pd.MultiIndex.from_product([[new_col_name], df2.columns.tolist()])
    return pd.concat([df, tmp], axis=1)

предполагая, что у нас есть следующий DF, и мы хотим добавить третий «многостолбец» — C:

In [114]: d
Out[114]:
   A        B
   a  b  c  a  b  c
0  5  5  7  0  7  2
1  5  3  9  0  5  5
2  5  8  5  5  5  7
3  5  4  5  4  5  2

используя нашу функцию:

In [132]: add_multicolumn(d, d2, 'C')
Out[132]:
   A        B        C
   a  b  c  a  b  c  a  b  c
0  5  5  7  0  7  2  0  7  2
1  5  3  9  0  5  5  0  5  5
2  5  8  5  5  5  7  5  5  7
3  5  4  5  4  5  2  4  5  2

СТАРЫЙ ответ:

вы можете сделать это с помощью pd.concat():

In [35]: d = pd.concat({'A':d['A'], 'B':d2}, axis=1)

In [36]: d
Out[36]:
   A        B
   a  b  c  a  b  c
0  7  3  9  0  7  2
1  9  4  5  0  5  5
2  7  6  1  5  5  7
3  2  5  7  4  5  2

Объяснение:

In [37]: d['A']
Out[37]:
   a  b  c
0  7  3  9
1  9  4  5
2  7  6  1
3  2  5  7

In [40]: pd.concat({'A':d['A'], 'B':d2}, axis=1)
Out[40]:
   A        B
   a  b  c  a  b  c
0  5  5  7  0  7  2
1  5  3  9  0  5  5
2  5  8  5  5  5  7
3  5  4  5  4  5  2
person MaxU    schedule 27.05.2016
comment
Отлично, похоже, это может сработать. Любая идея, есть ли метод DataFrame, который может это сделать (например, d.some_set_method('B', d2))? - person beardc; 27.05.2016
comment
На самом деле я предпочитаю старый ответ, так как он не требует написания дополнительной функции. Я хотел спросить, есть ли уже встроенный метод для DataFrame, поскольку в наши дни у них, похоже, много функций, доступных для встроенных методов. - person beardc; 27.05.2016
comment
@beardc, старый ответ не позволит вам добавить новый мультистолбец, если в вашем DF уже есть более одного мультистолбца. Но вам не нужно использовать эту функцию, вам просто нужно подготовить/установить соответствующие несколько столбцов в DF, который вы собираетесь добавить - person MaxU; 27.05.2016