У меня есть следующие значения df
,
code post_date inv_date year_month
750 2017-12-11 2017-11-29 201711
750 2017-12-12 2017-11-30 201711
750 2017-12-13 2017-12-01 201712
750 2017-12-14 2017-12-02 201712
750 2017-12-15 2017-12-03 201712
760 2017-12-16 2017-12-04 201711
760 2017-12-05 2017-12-05 201711
760 2017-12-28 2017-12-16 201711
760 2017-12-29 2017-12-17 201712
760 2017-12-30 2017-12-18 201712
Сначала я groupby
code
и year_month
,
df_grp_by = df.groupby(['code', 'year_month'])
, а затем вычисляю среднее число днейpost_date
- inv_date
в каждой группе,
df_avg_proc_days = df_grp_by.apply(lambda row: (row['post_date'] -row['inv_date']).dt.days).mean(level=[0, 1]).reset_index(name='avg_days')
Я хотел бы получить новый df
сверху, выглядит следующим образом:
0 1 2 3
0 -1 0 201711 201712
1 0 10.8 9.6 12
2 750 12 12 12
3 760 9.6 8 12
-1
являетсяфиктивное значение для поддержания формы матрицы;0
представляет «все» значения, которые усредняют значения code
или year_month
или code
и year_month
, например, ячейка (1,1)
составляет в среднем post_date - inv_date
для всех строк в df
;(1,2)
в среднем post_date - inv_date
для 201711
во всех строках, которые имеют это значение для year_month
в df
.
Я попытался использовать следующий код для генерации матрицы,
def convert_to_matrix(df, p_tab_idx, p_tab_cols, p_tab_vals, p_tab_agg_func, fill_na=-1):
df_tab = (df.pivot_table(index=p_tab_idx,
columns=p_tab_cols,
values=p_tab_vals,
margins=True,
aggfunc=p_tab_agg_func,
fill_value=fill_na,
margins_name='0'))
# change order of index and columns values for reindex
idx = df_tab.index[-1:].tolist() + df_tab.index[:-1].tolist()
cols = df_tab.columns[-1:].tolist() + df_tab.columns[:-1].tolist()
df_tab = (df_tab.reindex(index=idx, columns=cols)
.reset_index()
.rename(columns={p_tab_idx: -1})
.rename_axis(None, 1))
# add columns to first row
df_tab = df_tab.columns.to_frame().T.append(df_tab).reset_index(drop=True)
# reset columns names to range
df_tab.columns = range(len(df_tab.columns))
# converts column labels from int to str
df_tab.columns = df_tab.columns.astype(str)
return df_tab
df_p_tab = convert_to_matrix(df_avg_proc_days,
p_tab_idx='code',
p_tab_cols='year_month',
p_tab_vals='avg_days',
p_tab_agg_func='mean')
но это генерирует,
0 1 2 3
0 -1 0 201711 201712
1 0 11 10 12
2 750 12 12 12
3 760 10 8 12
Мне интересно, как это исправить.