Есть ли лучший / более эффективный способ сделать это (векторизация)?Очень медленная работа с применением панд - PullRequest
0 голосов
/ 09 июня 2018

Так что в R я бы использовал оптимизированную функцию apply для этого, но я прочитал теперь, что функция apply Panda представляет собой абстрагированный цикл и, возможно, даже медленнее, чем один, и это проявляется в производительности.На моей машине потребовалось 30 минут, чтобы обработать 60 тыс. Строк.

По сути, я рассчитываю рассчитать скользящее среднее на основе набора данных с различными группами, по которым мне нужно рассчитать скользящее среднее.Таких групп много.Поэтому я, по сути, сначала должен установить подмножество набора данных на основе строк / ячеек, и только потом вычислять скользящее среднее.

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

Мое текущее решение использует функцию применения, которая действительно проста для понимания и поддержки:

df['SMA'] = df.apply(SMA, axis=1)

def SMA(row):
     Subset = df[(df['group']==row['group'])&(df['t']<=row['t'])].reset_index()
     Subset2 = Subset[len(Subset.index)-(2):len(Subset.index)]
     return df['val'].mean()

Это мой ожидаемый результат (который я в настоящее время получаю, но очень очень медленно):

Это фрейм данных, и в этом примере мне нужна скользящая средняя по двум временным точкам, в этом примере - "t":

t   group   val moving average
1   A        1  NA
2   A        2  1.5
3   A        3  2.5
1   B        4  NA
2   B        5  4.5
3   B        6  5.5
1   C        7  NA
2   C        8  7.5
3   C        9  8.5

1 Ответ

0 голосов
/ 09 июня 2018

Этот вид операции (разбиение на группы) обрабатывается методом .groupby в пандах.Если мы позаботимся о том, чтобы установить индекс на время, он также даст нам правильный вывод с обратным индексом времени.

Вот пример, который в основном совпадает с вашим кодом:

df = pandas.DataFrame(
   [[1, 'A', 1], 
    [2, 'A', 2], 
    [3, 'A', 3], 
    [1, 'B', 4], 
    [2, 'B', 5], 
    [3, 'B', 6], 
    [1, 'C', 7], 
    [2, 'C', 8], 
    [3, 'C', 9]],
    columns=['t', 'group', 'val'])

df = df.set_index('t')
moving_avg = df.groupby('group').rolling(2).mean()

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

         val
group t     
A     1  NaN
      2  1.5
      3  2.5
B     1  NaN
      2  4.5
      3  5.5
C     1  NaN
      2  7.5
      3  8.5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...