В pandas как применить функцию к каждому столбцу, который возвращает два столбца - PullRequest
1 голос
/ 02 февраля 2020

Я хотел бы применить функцию к каждому столбцу моего сгруппированного мультииндекса pandas dataframe.

Если бы у меня была функция my_function(), которая возвращает скаляр, я бы использовал

data_grouped = data.groupby(['type'])
data_transf = data_grouped.apply(lambda x: my_function(x))

Однако рассмотрим другую функцию my_function_array(), которая принимает массив (все n строк в одной группе) в качестве входных данных и возвращает массив n x 2 в качестве выходных данных.

Как я могу применить это к каждому столбцу моего сгруппированного фрейма данных data_grouped? То есть я хочу взять каждый столбец моих сгруппированных данных из m строк и заменить его на n x 2 вывод my_function_array().

Вот некоторые примеры данных. Есть и другие группы (типы), но я показываю только одну

type   frame   x            y           
F1675      1   77.369027    108.013249
           2   107.784096   22.177883
           3   22.385162    65.024619
           4   65.152003    77.74970

def my_function_array(data_vec, D=2, T=2):

    N = len(data_vec) - (D-1)*T # length of embedded signal
    embed_data = np.zeros([N,D])

    for di in range(-D//2,D//2):
        embed_data[:,di] = data_vec[ np.arange((D//2+di)*T, N+(D//2+di)*T) ]         

    return embed_data

Применим функцию ко второму столбцу y

my_function_array(np.array([108.013249, 22.177883, 65.024619, 77.74970]))

У меня

array([[ 65.024619, 108.013249],
       [ 77.7497  ,  22.177883]])

Таким образом, ожидаемый результат равен

    type   frame   x_1          x_2        y_1         y_2
   F1675       1   22.385162    77.369027   65.024619  108.013249
               2   65.152003   107.784096   77.7497     22.177883

, где x_1 и x_2 - это два столбца, полученных в результате x (наименование не имеет значения, может быть любым). Обратите внимание, что группы стали короче и шире.

1 Ответ

1 голос
/ 02 февраля 2020

Я думаю, вам нужно вернуть pd.DataFrame:

def my_function_array(data_vec, D=2, T=2):
#    print (data_vec.name)

    N = len(data_vec) - (D-1)*T # length of embedded signal
    embed_data = np.zeros([N,D])

    for di in range(-D//2,D//2):
        embed_data[:,di] = data_vec[ np.arange((D//2+di)*T, N+(D//2+di)*T) ]         
    return pd.DataFrame(embed_data).add_prefix(data_vec.name)


f = lambda x: pd.concat([my_function_array(x[y]) for y in x], axis=1)

data_transf = data.groupby(['type']).apply(f)
print (data_transf)
                x0          x1         y0          y1
type                                                 
F1675 0  22.385162   77.369027  65.024619  108.013249
      1  65.152003  107.784096  77.749700   22.177883
...