Как создать продажи в этом году и в предыдущем году в двух разных столбцах?

Мне нужно создать два разных столбца: один для продаж в этом году и один для прошлогодних продаж на основе данных транзакционного уровня?

Формат данных:-

Date                | bill amount
  1. 2019-07-22 | 500
  2. 2019-07-25 | 200
  3. 2020-11-15 | 100
  4. 2020-11-06 | 900
  5. 2020-12-09 | 50
  6. 2020-12-21 | 600

Требуемый формат: -

Год_месяц | Продажи в этом месяце | Распродажа за предыдущий месяц

  1. 2019_07 | 700 | -
  2. 2020_11 | 1000 | -
  3. 2020_12 | 650 | 1000

person ROHITH REDDY SUREDDY    schedule 25.11.2020    source источник


Ответы (2)


Относительно непросто выяснить, каков был предыдущий месяц. Мы делаем это, вычисляя начало месяца для каждой даты, а затем откатываясь на 1 месяц. Обратите внимание, что это касается вопросов января - ›декабря прошлого года.

Начнем с создания образца фрейма данных и импорта некоторых полезных модулей.

from io import StringIO
from datetime import datetime,timedelta
from dateutil.relativedelta import relativedelta
data = StringIO(
"""
date|amount
2019-07-22|500
2019-07-25|200
2020-11-15|100
2020-11-06|900
2020-12-09|50
2020-12-21|600
""")
df = pd.read_csv(data,sep='|')
df['date'] = pd.to_datetime(df['date'])
df

мы получаем


    date        amount
0   2019-07-22  500
1   2019-07-25  200
2   2020-11-15  100
3   2020-11-06  900
4   2020-12-09  50
5   2020-12-21  600

Затем мы вычисляем начало месяца и начало предыдущего месяца с помощью утилит datetime.

df['month_start'] = df['date'].apply(lambda d:datetime(year = d.year, month = d.month, day = 1))
df['prev_month_start'] = df['month_start'].apply(lambda d:d+relativedelta(months = -1))

Затем мы суммируем ежемесячные продажи, используя groupby в начале месяца.

ms_df = df.drop(columns = 'date').groupby('month_start').agg({'prev_month_start':'first','amount':sum}).reset_index()
ms_df

так что мы получаем

    month_start prev_month_start    amount
0   2019-07-01  2019-06-01          700
1   2020-11-01  2020-10-01          1000
2   2020-12-01  2020-11-01          650

Затем мы присоединяемся (объединяем) ms_df к самому себе, сопоставляя 'prev_month_start' с 'month_start'

ms_df2 = ms_df.merge(ms_df, left_on='prev_month_start', right_on='month_start', how = 'left', suffixes = ('','_prev'))

Мы более или менее там, но теперь делаем это красиво, избавляясь от лишних столбцов, добавляя метки и т. Д.

ms_df2['label'] = ms_df2['month_start'].dt.strftime('%Y_%m')
ms_df2 = ms_df2.drop(columns = ['month_start','prev_month_start','month_start_prev','prev_month_start_prev'])
columns = ['label','amount','amount_prev']
ms_df2 = ms_df2[columns]

и мы получаем

|    |   label |   amount |   amount_prev |
|---:|--------:|---------:|--------------:|
|  0 | 2019_07 |      700 |           nan |
|  1 | 2020_11 |     1000 |           nan |
|  2 | 2020_12 |      650 |          1000 |
person piterbarg    schedule 25.11.2020

Используя данные @piterbarg, мы можем использовать resample в сочетании с shift и concat для получения желаемых данных:

import pandas as pd
from io import StringIO
data = StringIO(
    """
date|amount
2019-07-22|500
2019-07-25|200
2020-11-15|100
2020-11-06|900
2020-12-09|50
2020-12-21|600
"""
)
df = pd.read_csv(data, sep="|", parse_dates=["date"])
df

        date    amount
0   2019-07-22  500
1   2019-07-25  200
2   2020-11-15  100
3   2020-11-06  900
4   2020-12-09  50
5   2020-12-21  600

Получите сумму за текущие продажи:

data = df.resample(on="date", rule="1M").amount.sum().rename("This_month")
data

date
2019-07-31     700
2019-08-31       0
2019-09-30       0
2019-10-31       0
2019-11-30       0
2019-12-31       0
2020-01-31       0
2020-02-29       0
2020-03-31       0
2020-04-30       0
2020-05-31       0
2020-06-30       0
2020-07-31       0
2020-08-31       0
2020-09-30       0
2020-10-31       0
2020-11-30    1000
2020-12-31     650
Freq: M, Name: This_month, dtype: int64

Теперь мы можем сдвинуть месяц, чтобы получить значения за предыдущий месяц, и отбросить строки с 0 в качестве общего объема продаж, чтобы получить окончательный результат:

(pd.concat([data, data.shift().rename("previous_month")], axis=1)
 .query("This_month!=0")
 .fillna(0))

          This_month    previous_month
date        
2019-07-31  700         0.0
2020-11-30  1000        0.0
2020-12-31  650         1000.0
person sammywemmy    schedule 26.11.2020