Панды создают и извлекают временные ряды в новый массив данных - PullRequest
0 голосов
/ 04 ноября 2018

Имеют следующий упрощенный фрейм данных:

Date           Name       Score       V       H       M
2018-01-01       A          5         V1      H4      M6
2018-01-01       B          3         V5      H2      M1
2018-01-01       C          4         V7      H6      M6
2018-01-01       A          4         V11     H9      M3
2018-01-01       C          2         V4      H2      M18
2018-01-02       A          4         V9      H1      M9
2018-01-02       B          1         V15     H4      M10
2018-01-02       A          3         V10     H10     M14
2018-01-03       C          5         V5      H21     M34
2018-01-04       A          3         V8      H9      M6
2018-01-04       A          4         V4      H15     M9
2018-01-04       C          2         V2      H4      M14
2018-01-04       B          5         V1      H1      M2

Рассматривая приведенный выше фрейм данных как необработанный набор, я дополнительно проиндексировал его по дате и пересчитал на уровне месяца. В конечном итоге я хотел бы создать отдельные временные ряды для уникальных значений в столбцах (Имя, V, H, M) по отношению к баллу (выполняется группированием). Несмотря на то, что я сократил выборку, я ожидаю нестандартных размеров временных рядов по сгруппированным уникальным значениям этих столбцов и планирую интерполировать, чтобы справиться с этим.

Цель состоит в том, чтобы создать и извлечь несколько временных рядов в новый фрейм данных и изучить их карты корреляции. Например, у меня будут отдельные временные ряды для V1, V2, ..., Vn, H1, H2, ..., Hn, M1, M2, ..., Mn и т. Д.

Я не уверен, что все это должно быть записано в одном новом кадре данных или нескольких кадрах данных на основе группирования. Вот пример того, как должен выглядеть вывод временных рядов:

        Date           Score         
V1      2018-01-01      4.5
        2018-02-01      4.1
        2018-03-01      4.3
        2018-04-01      4.2
        2018-05-01      4.4

        Date           Score         
V2      2018-01-01      4.5
        2018-02-01      4.1
        2018-03-01      4.3
        2018-04-01      4.2
        2018-05-01      4.4

        Date           Score         
V3      2018-01-01      4.5
        2018-02-01      4.1
        2018-03-01      4.3
        2018-04-01      4.2
        2018-05-01      4.4

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

Ценю любую помощь и руководство.

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

Я пробовал это с пандами 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
0 голосов
/ 05 ноября 2018

Вы можете использовать concat для перемещения столбцов Name, V, H, M друг над другом. После этого вы можете заполнить счет tile. Наконец, вы можете применить resample, mean и interpolate к таким группам, как:

import numpy as np

df['Date'] = pd.to_datetime(df['Date'])
df.set_index('Date', inplace=True)
df2 = pd.concat([df.Name, df.V, df.H, df.M]).to_frame(name='Name')
df2['Score'] = np.tile(df['Score'].values,4)
df2.groupby('Name').apply(lambda x: x.resample('M').mean().interpolate())
...