Панды, Расширяющие Среднее с Группой К и до текущей даты строки - PullRequest
0 голосов
/ 30 мая 2018

У меня есть кадр данных Pandas следующим образом

df = pd.DataFrame([['John', '1/1/2017','10'],
                   ['John', '2/2/2017','15'],
                   ['John', '2/2/2017','20'],
                   ['John', '3/3/2017','30'],
                   ['Sue', '1/1/2017','10'],
                   ['Sue', '2/2/2017','15'],
                   ['Sue', '3/2/2017','20'],
                   ['Sue', '3/3/2017','7'],
                   ['Sue', '4/4/2017','20']
                  ],
                   columns=['Customer', 'Deposit_Date','DPD'])

.Каков наилучший способ расчета столбца PreviousMean на снимке экрана ниже?

Столбец - это среднее значение DPD за год для данного клиента.Т.е. включает все DPD до, но не включая строки, которые соответствуют текущей дате депозита .Если никаких предыдущих записей не было, то это ноль или 0.

Снимок экрана: enter image description here

Примечания:

  • данные сгруппированы по имени клиента и расширяются по датам депозита
  • в каждой группе, среднее значение рассчитывается с использованием только значений из предыдущих строк.
  • вВ начале каждого нового клиента среднее значение равно 0 или, в качестве альтернативы, равно нулю, поскольку отсутствуют предыдущие записи, из которых можно сформировать среднее значение
  • . Фрейм данных упорядочен по имени клиента и Deposit_Date
.

Ответы [ 4 ]

0 голосов
/ 11 апреля 2019
0 голосов
/ 30 мая 2018

вместо группировки и расширения среднего, отфильтруйте кадр данных по условиям и вычислите среднее значение DPD:

  • Customer == текущей строки Customer
  • Deposit_Date <номер текущей строки <code>Deposit_Date

Используйте df.apply для выполнения этой операции для всей строки в кадре данных:

df['PreviousMean'] = df.apply(
    lambda x: df[(df.Customer == x.Customer) & (df.Deposit_Date < x.Deposit_Date)].DPD.mean(), 
axis=1)

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

  Customer Deposit_Date  DPD  PreviousMean
0     John   2017-01-01   10           NaN
1     John   2017-02-02   15          10.0
2     John   2017-02-02   20          10.0
3     John   2017-03-03   30          15.0
4      Sue   2017-01-01   10           NaN
5      Sue   2017-02-02   15          10.0
6      Sue   2017-03-02   20          12.5
7      Sue   2017-03-03    7          15.0
8      Sue   2017-04-04   20          13.0
0 голосов
/ 30 мая 2018

Хорошо, вот лучшее решение, которое я придумал.

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

s=df.groupby(['Customer Name','Deposit_Date'],as_index=False)[['DPD']].agg(['count','sum'])
s.columns = [' '.join(col) for col in s.columns]
s.reset_index(inplace=True)

s['DPD_CumSum']=s.groupby(['Customer Name'])[['DPD sum']].cumsum()
s['DPD_CumCount']=s.groupby(['Customer Name'])[['DPD count']].cumsum()
s['DPD_CumMean']=s['DPD_CumSum']/ s['DPD_CumCount']
s['DPD_PrevMean']=s.groupby(['Customer Name'])['DPD_CumMean'].shift(1)

df=df.merge(s[['Customer Name','Deposit_Date','DPD_PrevMean']],how='left',on=['Customer Name','Deposit_Date'])
0 голосов
/ 30 мая 2018

Вот один из способов исключить повторные дни из расчета среднего значения:

# create helper series which is NaN for repeated days, DPD otherwise
s = df.groupby(['Customer Name', 'Deposit_Date']).cumcount() == 1
df['DPD2'] = np.where(s, np.nan, df['DPD'])

# apply pd.expanding_mean
df['CumMean'] = df.groupby(['Customer Name'])['DPD2'].apply(lambda x: pd.expanding_mean(x))

# drop helper series
df = df.drop('DPD2', 1)

print(df)

  Customer Name Deposit_Date  DPD  CumMean
0          John   01/01/2017   10     10.0
1          John   01/01/2017   10     10.0
2          John   02/02/2017   20     15.0
3          John   03/03/2017   30     20.0
4           Sue   01/01/2017   10     10.0
5           Sue   01/01/2017   10     10.0
6           Sue   02/02/2017   20     15.0
7           Sue   03/03/2017   30     20.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...