Я пробовал это с пандами melt
. Я пытался использовать двойной melt
, но этот пост SO объяснил, что это невозможно, поэтому мне пришлось (1) melt
(стек) для столбцов, исключая Score
столбцы, чтобы дать df_modmelt
и затем (b) добавить новый столбец, который был просто повторяющейся версией Score
столбца , основанного на этой идее - по сути, один и тот же столбец был повторен (вертикально соединен) n
раз Я сделал это, используя (len(df_modmelt)/len(df))
. Это оправдано, потому что после расплавления я не изменил порядок строк, поэтому каждый блок в расплавленном фрейме данных df_modmelt
находится в том же порядке, что и исходные данные, и добавление столбца Scores
сохраняет связь между столбцом Scores
и др. Тогда просто используйте Grouper
с key='Date'
и freq='M'
.
Вот пример кода (я добавил 3 строки к вашим образцам данных, чтобы получить значения за 2 месяца)
df['Date'] = pd.to_datetime(df['Date'])
Date Name Score V H M
0 2018-01-01 A 5 V1 H4 M6
1 2018-01-01 B 3 V5 H2 M1
2 2018-01-01 C 4 V7 H6 M6
3 2018-01-01 A 4 V11 H9 M3
4 2018-01-01 C 2 V4 H2 M18
5 2018-01-02 A 4 V9 H1 M9
6 2018-01-02 B 1 V15 H4 M10
7 2018-01-02 A 3 V10 H10 M14
8 2018-01-03 C 5 V5 H21 M34
9 2018-01-04 A 3 V8 H9 M6
10 2018-01-04 A 4 V4 H15 M9
11 2018-01-04 C 2 V2 H4 M14
12 2018-01-04 B 5 V1 H1 M2
13 2018-02-01 A 4 V5 H11 M9
14 2018-02-01 C 2 V7 H5 M14
15 2018-02-02 B 5 V1 H7 M2
код
cols = ['V','H','M','Name']
df_modmelt = (df[['Date']+cols]
.melt(id_vars=['Date'],
var_name='column',
value_name='value'))
df_modmelt['Score'] = (pd.concat([df['Score']]*(len(df_modmelt)/len(df)))
.reset_index(drop=True))
df_final = (df_modmelt
.groupby(['column','value', pd.Grouper(key='Date', freq='M')])['Score']
.mean()
.reset_index(drop=False))
df_final['Date'] = df_final['Date'].dt.floor('d') - pd.offsets.MonthBegin(1)
print(df_final)
Вот вывод
column value Date Score
0 H H1 2018-01-01 4.500000
1 H H10 2018-01-01 3.000000
2 H H11 2018-02-01 4.000000
3 H H15 2018-01-01 4.000000
4 H H2 2018-01-01 2.500000
5 H H21 2018-01-01 5.000000
6 H H4 2018-01-01 2.666667
7 H H5 2018-02-01 2.000000
8 H H6 2018-01-01 4.000000
9 H H7 2018-02-01 5.000000
10 H H9 2018-01-01 3.500000
11 M M1 2018-01-01 3.000000
12 M M10 2018-01-01 1.000000
13 M M14 2018-01-01 2.500000
14 M M14 2018-02-01 2.000000
15 M M18 2018-01-01 2.000000
16 M M2 2018-01-01 5.000000
17 M M2 2018-02-01 5.000000
18 M M3 2018-01-01 4.000000
19 M M34 2018-01-01 5.000000
20 M M6 2018-01-01 4.000000
21 M M9 2018-01-01 4.000000
22 M M9 2018-02-01 4.000000
23 Name A 2018-01-01 3.833333
24 Name A 2018-02-01 4.000000
25 Name B 2018-01-01 3.000000
26 Name B 2018-02-01 5.000000
27 Name C 2018-01-01 3.250000
28 Name C 2018-02-01 2.000000
29 V V1 2018-01-01 5.000000
30 V V1 2018-02-01 5.000000
31 V V10 2018-01-01 3.000000
32 V V11 2018-01-01 4.000000
33 V V15 2018-01-01 1.000000
34 V V2 2018-01-01 2.000000
35 V V4 2018-01-01 3.000000
36 V V5 2018-01-01 4.000000
37 V V5 2018-02-01 4.000000
38 V V7 2018-01-01 4.000000
39 V V7 2018-02-01 2.000000
40 V V8 2018-01-01 3.000000
41 V V9 2018-01-01 4.000000
Редактировать
последняя строка pd.offsets.MonthBegin(1)
просто возвращает первую дату месяца.
РЕДАКТИРОВАТЬ 2
По запросу для получения дополнительной информации о корреляции между уникальными значениями в столбце value
из df_final
- см. Полезные ссылки здесь :
for c in ['Name','H']:
df_pivot = (df_final[df_final.value.isin(df[c].unique().tolist())]
.pivot_table(index='Date', columns='value', values='Score'))
Выход для столбца Name
print(df_pivot)
value A B C
Date
2018-01-01 3.833333 3.0 3.25
2018-02-01 4.000000 5.0 2.00
print(df_pivot.corr())
value A B C
value
A 1.0 1.0 -1.0
B 1.0 1.0 -1.0
C -1.0 -1.0 1.0
Вывод для столбца H
print(df_pivot)
value H1 H10 H11 H15 H2 H21 H4 H5 H6 H7 H9
Date
2018-01-01 4.5 3.0 NaN 4.0 2.5 5.0 2.666667 NaN 4.0 NaN 3.5
2018-02-01 NaN NaN 4.0 NaN NaN NaN NaN 2.0 NaN 5.0 NaN
print(df_pivot.corr())
value H1 H10 H11 H15 H2 H21 H4 H5 H6 H7 H9
value
H1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
H10 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
H11 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
H15 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
H2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
H21 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
H4 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
H5 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
H6 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
H7 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
H9 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN