Панды Датафрейм. Разверните значения кортежа как столбцы с мультииндексом - PullRequest
1 голос
/ 15 октября 2019

У меня есть фрейм данных df:

                A    B
first second          
bar   one     0.0  0.0
      two     0.0  0.0
foo   one     0.0  0.0
      two     0.0  0.0

Я преобразую его в другой, где значения являются кортежами:

                      A          B
first second                      
bar   one     (6, 1, 0)  (0, 9, 3)
      two     (9, 3, 4)  (6, 2, 1)
foo   one     (1, 9, 0)  (4, 0, 0)
      two     (6, 1, 5)  (8, 3, 5)

У меня вопрос, как его получить (expanded) чтобы быть как ниже, где значения кортежей становятся столбцами с мультииндексом? Могу ли я сделать это в течение transform или сделать это в качестве дополнительного шага после transform?

                   A       B
               m n k   m n k            
first second   
bar   one      6 1 0   0 9 3
      two      9 3 4   6 2 1
foo   one      1 9 0   4 0 0
      two      6 1 5   8 3 5

Код для вышеперечисленного:

import numpy as np
import pandas as pd

np.random.seed(123)


def expand(s):
    # complex logic of `result` has been replaced with `np.random`
    result = [tuple(np.random.randint(10, size=3)) for i in s]
    return result


index = pd.MultiIndex.from_product([['bar', 'foo'], ['one', 'two']], names=['first', 'second'])
df = pd.DataFrame(np.zeros((4, 2)), index=index, columns=['A', 'B'])
print(df)

expanded = df.groupby(['second']).transform(expand)
print(expanded)

Ответы [ 2 ]

1 голос
/ 15 октября 2019

Попробуйте это:

df_lst = []
for col in df.columns:
    expanded_splt = expanded.apply(lambda x: pd.Series(x[col]),axis=1)
    columns  = pd.MultiIndex.from_product([[col], ['m', 'n', 'k']])
    expanded_splt.columns = columns
    df_lst.append(expanded_splt)
pd.concat(df_lst, axis=1)

Вывод:

                A           B
                m   n   k   m   n   k
first   second                      
bar     one     6   1   0   0   9   3
        two     9   3   4   6   2   1
foo     one     1   9   0   4   0   0
        two     6   1   5   8   3   5
0 голосов
/ 24 октября 2019

Наконец-то я нашел время найти ответ, который меня устраивает.

expanded_data = expanded.agg(lambda x: np.concatenate(x), axis=1).to_numpy()
expanded_data = np.stack(expanded_data)
column_index = pd.MultiIndex.from_product([expanded.columns, ['m', 'n', 'k']])
exploded = pd.DataFrame(expanded_data, index=expanded.index, columns=column_index)
print(exploded)
              A        B      
              m  n  k  m  n  k
first second                  
bar   one     6  1  0  0  9  3
      two     9  3  4  6  2  1
foo   one     1  9  0  4  0  0
      two     6  1  5  8  3  5

...