Прокрутка панд применяется к df, где фильтр основан на значениях в текущей строке

У меня есть фреймворк Pandas со столбцом datetime (который я использовал как DatetimeIndex), который имеет категориальный столбец и числовой столбец. Я хотел бы применить сложную функцию к числовому столбцу, когда категориальный столбец совпадает с текущей строкой, в коротком (десятидневном) окне, отстающем от текущей строки (не включительно).

В качестве надуманного примера:

name = ['steve', 'bob', 'harry', 'jeff'] * 5
df = pd.DataFrame(
    index=pd.DatetimeIndex(start='2018-10-10', end='2018-10-29', freq='D'), 
    data = {'value': [x for x in range(20)],
          'name': names
         }
)

создает простой фрейм данных, к которому я хотел бы добавить еще один столбец (result), который вычисляет количество строк * сумму значений в 'value' (или что-то в этом роде - просто формула, в которой нет встроенной функции Pandas за). Итак, для фрейма данных выше я бы хотел следующее:

            num   name  result
2018-10-10    0  steve     NaN    
2018-10-11    1    bob     NaN
2018-10-12    2  harry     NaN
2018-10-13    3   jeff     NaN
2018-10-14    4  steve       0
2018-10-15    5    bob       1
2018-10-16    6  harry       2
2018-10-17    7   jeff       3
2018-10-18    8  steve       8
2018-10-19    9    bob      12
2018-10-20   10  harry      16
2018-10-21   11   jeff      20
2018-10-22   12  steve      24
2018-10-23   13    bob      28
2018-10-24   14  harry      32
2018-10-25   15   jeff      36
2018-10-26   16  steve      40
2018-10-27   17    bob      44
2018-10-28   18  harry      48
2018-10-29   19   jeff      52

Я могу написать для этого свою функцию и использовать ее в pandas.apply:

def rolling_apply(df, time, window_size=timedelta(days=10)):
    event_time = time
    event_name = df[df.index == time]['names'].iloc[0]

    return df[
        (df['names'] == event_name) & 
        (df.index < event_time) & 
        (df.index >= event_time - window_size)
    ]

df['result'] = df.apply(lambda x: rolling_apply(df, x.name)['value'].sum() * rolling_apply(df, x.name).count(), axis=1)

но производительность довольно быстро падает по мере роста моих данных. pandas.rolling.apply кажется подходящим, но я не могу приспособить его к тому, чем я хочу заниматься.

Любые предложения или помощь будут очень признательны!

«Я могу написать для этого свою функцию и использовать ее в pandas.apply» - покажите код.

John Zwinck 27.12.2018 04:57

Из этого не ясна логика, не могли бы вы объяснить еще немного?

cs95 27.12.2018 05:36

Отредактировано, чтобы показать код, который я пробовал.

bigsim 27.12.2018 09:22
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
438
0

Другие вопросы по теме