Примените функцию к фрейму данных pandas и получите выходные данные ndarray разного размера

#python #python-3.x #pandas #scipy

#python #python-3.x #pandas #scipy

Вопрос:

Моя цель — получить индексы локальных максимальных высот фрейма данных. Они варьируются от 3 до 5 для каждого столбца.

Я пробовал использовать функцию apply, но получаю либо сообщение об ошибке Shape of passed values is (736, 4), indices imply (736, 480) , либо could not broadcast input array from shape (0) into shape (1) .

Моя матрица 480x736 .

Вот что я написал для функции apply:

 import numpy as np
import peakutils
df.apply(lambda x: peakutils.indexes(x, thres=0.02/max(x), min_dist=100))
 

Вот что я могу заставить работать:

 indexes =[]
import numpy as np
import peakutils
for column in df:
    indexes.append(peakutils.indexes(df[column], thres=0.02/max(df[column]), min_dist=100))
 

Часто индексы имеют длину 4, но иногда я получаю на 1 больше или меньше:

 Out[32]: 
[array([ 12, 114, 217, 328, 433]),
 array([ 12, 116, 217, 325, 433]),
 array([ 64, 166, 283, 389]),
 array([105, 217, 326, 433]),
 array([105, 237, 390])]
 

Я предполагаю, что проблема с выводом возникает из-за того, что я не знаю форму результирующего фрейма данных. Форма не поддается определению с самого начала.

Как мне применить функцию к df, где выходные данные отличаются по размеру и типу?

Комментарии:

1. Я могу заставить его работать с scipy, df.apply(lambda x: find_peaks_cwt(x, np.arange(1, 200))) , но это намного медленнее и не так чисто.

2.оберните lambda возвращаемое значение в pd.Series df.apply(lambda x: pd.Series(peakutils.indexes(x, thres=0.02/max(x), min_dist=100)))

3. Я могу принять ответ, если вы хотите опубликовать его как один. Однако я не понимаю, почему это не удалось.

Ответ №1:

pandas пытается сделать «что-то» с массивами. Вы можете замкнуть это «что-то», обернув lambda возвращаемое значение в pd.Series

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

 df.apply(lambda x: pd.Series(peakutils.indexes(x, thres=0.02/max(x), min_dist=100)))