Создайте новый фрейм данных с условием для каждой группы в pandas - PullRequest
0 голосов
/ 17 апреля 2020

Я пытаюсь создать новый фрейм данных на основе условий для каждой группы. Предположим, у меня есть фрейм данных с именем, флагом и месяцем.

import pandas as pd
import numpy as np

data = {'Name':['A', 'A', 'B', 'B'], 'Flag':[0, 1, 0, 1], 'Month':[1,2,1,2]}

df = pd.DataFrame(data)

need = df.loc[df['Flag'] == 0].groupby(['Name'], as_index = False)['Month'].min()

Мое условие - найти минимальный месяц, в котором флаг равен 0 для имени.

Я использовал .loc, чтобы определить Мое состояние работает нормально, но я обнаружил, что при применении с 10 миллионами строк производительность довольно низкая.

Есть ли более эффективный способ сделать это?

Спасибо!

1 Ответ

0 голосов
/ 17 апреля 2020

Вчера у меня был тот же сценарий, где я сократил 90 секунд до 3 секунд. Поскольку скорость - ваша проблема (как и у меня), а не использование только Pandas, я бы рекомендовал использовать Numba и NumPy. Уловка в том, что вам придется взяться за sh структуры и типы данных, чтобы получить хорошее представление о том, что Numba действительно делает с JIT. Однако, как только вы это сделаете, это будет круто.

Я бы порекомендовал найти способ получить каждое значение в вашем DataFrame в целое число. Для колонки вашего имени попробуйте уникальные идентификаторы. Флаг и месяц уже выглядят хорошо.

name_ids = []
for i, name in enumerate(np.unique(df["Name"])):
  name_ids.append({i: name})

Затем создайте функцию и l oop по старинке:

@njit
def really_fast_numba_loop(data):
  for row in data:
    # do stuff
  return data

new_df = really_fast_numba_loop(data)

При первом вызове вашей функции в вашем Файл, он будет примерно с той же скоростью, что и в других местах, но все остальное время будет молниеносно. Итак, хитрость заключается в том, чтобы найти баланс между тем, что поместить в функцию, и тем, что нужно поместить в ее внешнюю область l oop.

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

Et voila. Вы просто победили Pandas iterrows / itertuples.

Прокомментируйте, если у вас есть вопросы!

...