Данные фильтра на основе месяца, идентификатора и суммы в Pandas - PullRequest
0 голосов
/ 11 марта 2020

ID. Email. Amount Date 1. wi@gn.c. 20 26-11-19 12.06.36.726000 2. wi@gn.c. 40 26-12-19 12.06.37.293000 3. by@gn.c. 50 26-11-19 12.06.37.960000 4. wi@gn.c. 20 26-01-20 12.06.51.306000 5. wi@gn.c. 60 26-02-20 12.06.52.458000 6. by@gn.c. 15 26-08-19 12.06.58.397000 7. wi@gn.c. 37 26-12-19 12.07.00.191000 5. wi@gn.c. 60 26-02-20 12.06.52.458000 6. by@gn.c. 15 26-08-19 12.06.58.397000 7. wi@gn.c. 37 26-12-19 12.07.00.191000

Мне нужно получить общую сумму для каждого адреса электронной почты за последние 1, 3 и 6 месяцев. Я пробовал несколько комбинаций команд, но сейчас я потерян.

В другом ответе df.groupby('Email')['Amount'].sum().reset_index() работает, но мне нужно добавить сумму на основе 1 Месяца, 3 месяцев и 6 месяцев.

Ожидаемый результат будет выглядеть следующим образом

ID. Email. Total for past 1 Month Total for past 3 Month Total for past 6 Month 1. wi@gn.c. 20 40 60 3. by@gn.c. 50 50 100

Примечание: окончательные цифры не совсем верны, я просто пытаюсь нарисовать картину того, что я пытаюсь сделать.

1 Ответ

0 голосов
/ 11 марта 2020

Надеюсь, это поможет: сначала преобразуйте столбец «Дата» в DateTimeIndex. Затем вам нужно разделить ваши данные на группы по 1 месяцу, 3 месяцам и 6 месяцам и создать 3 dfs. Суммируйте эти 3 значения по сумме «Сумма». Наконец, объедините все эти 3 dfs в столбце «Электронная почта».

import numpy as np
import pandas as pd

df = pd.DataFrame([[1,'wi@gn.c.',20,'26-11-19 12.06.36.726000'],
                   [2,'wi@gn.c.',40,'26-12-19 12.06.37.293000'],
                   [3,'by@gn.c.',50,'26-11-19 12.06.37.960000'],
                   [4,'wi@gn.c.',20,'26-01-20 12.06.51.306000'],
                   [5,'wi@gn.c.',60,'26-02-20 12.06.52.458000'],
                   [6,'by@gn.c.',15,'26-08-19 12.06.58.397000'],
                   [7,'wi@gn.c.',37,'26-12-19 12.07.00.191000'],
                   [6,'wi@gn.c.',60,'26-02-20 12.06.52.458000'],
                   [7,'by@gn.c.',15,'26-08-19 12.06.58.397000'],
                   [8,'wi@gn.c.',37,'26-12-19 12.07.00.191000']],
                  columns=['ID','Email','Amount','Date'])

# convert your 'Date' to datetimeindex
df['Date'] = pd.to_datetime(df['Date'], format = '%d-%m-%y %H.%M.%S.%f')
df.set_index('Date', inplace=True)
df.sort_index(inplace=True)

# create dfs from base df for past 1 month, 3 months and 6 months data and aggregate by sum of 'Amount'
end = pd.datetime.now()
df_1mo = df.loc[end - pd.DateOffset(months=1): end].groupby('Email')['Amount'].agg(total_1mo=np.sum)
df_3mo = df.loc[end - pd.DateOffset(months=3): end].groupby('Email')['Amount'].agg(total_3mo=np.sum)
df_6mo = df.loc[end - pd.DateOffset(months=6): end].groupby('Email')['Amount'].agg(total_6mo=np.sum)

# merge all 3 dfs on 'Email'
print(df_1mo.merge(df_3mo, on='Email', how='outer').merge(df_6mo, on='Email', how='outer').fillna(0))

Выходные данные:

          total_1mo  total_3mo  total_6mo
Email                                    
wi@gn.c.      120.0      254.0        274
by@gn.c.        0.0        0.0         50
  • За последний месяц (11 февраля - 11 марта) у вас есть только 2 строки с Date как 02/26, как с Email wi@gn.c., так и с суммой Amount 60 + 60 = 120.
  • За последние 3 месяца (De c 11-Mar 11) у вас есть 6 строк с Date как 02/26/2020, 26/26/2020 и 26/12/2019, все с то же самое Email wi@gn.c. и сумма Amount составляет 60 + 60 + 20 + 37 + 37 + 40 = 254.
  • За последние 6 месяцев (11 сентября - 11 марта) у вас есть 8 строк с Date как 02/26/2020, 01/26/2020, 12/26/2020 и 11/26 / 2019. Из этого одного ряда с Email by@gn.c. и Amount как 50. Все остальные ряды с Email wi@gn.c., а сумма Amount составляет 60 + 60 + 20 + 37 + 37 + 40 +. 20 = 274.
  • Другие 2 строки с Date как 26.08.2020 не находятся в этом диапазоне 6 месяцев, поэтому они исключены.

Надеюсь, это объясняет ответ. Вы можете изменить дату end на другую дату, чтобы установить базовую дату. Здесь я использовал текущую дату в качестве базовой даты.

Возможно, для этого найдется более эффективное решение. Но это должно работать на основе вашего образца данных. Дайте мне знать, как это происходит.

Обновление: минимальное и максимальное:

df_1mo = df.loc[end - pd.DateOffset(months=1): end].groupby('Email')['Amount'].agg(total_1mo=np.max)
df_3mo = df.loc[end - pd.DateOffset(months=3): end].groupby('Email')['Amount'].agg(total_3mo=np.max)
df_6mo = df.loc[end - pd.DateOffset(months=6): end].groupby('Email')['Amount'].agg(total_6mo=np.max)

# merge all 3 dfs on 'Email'
print(df_1mo.merge(df_3mo, on='Email', how='outer').merge(df_6mo, on='Email', how='outer').fillna(0))

Вывод:

          total_1mo  total_3mo  total_6mo
Email                                    
wi@gn.c.       60.0       60.0         60
by@gn.c.        0.0        0.0         50
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...