Панды: сложное объединение DataFrames с базой данных - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть 2 панды DataFrame, которые мне нужно немного сложнее объединить, поэтому мне нужна некоторая помощь.

DataFrame для вставки:

            AAPL shares  GOOG shares  MSFT shares
date                                             
2019-01-01          0.0         10.0          0.0
2019-01-05          0.0          0.0         15.0
2019-01-12          0.0          0.0          7.0
2019-01-13          3.0          0.0          0.0
2019-01-14          0.0         -5.0          0.0

DataFrame для получения вставки

               0      1           2        3           4       5
0     1998-01-02  16.25  2014-03-27   558.46  1998-01-02  131.13
1     1998-01-05  15.88  2014-03-28   559.99  1998-01-05  130.38
2     1998-01-06  18.94  2014-03-31   556.97  1998-01-06  131.13
3     1998-01-07  17.50  2014-04-01   567.16  1998-01-07  129.56
4     1998-01-08  18.19  2014-04-02   567.00  1998-01-08  130.50
5     1998-01-09  18.19  2014-04-03   569.74  1998-01-09  127.00
6     1998-01-12  18.25  2014-04-04   543.14  1998-01-12  129.50
7     1998-01-13  19.50  2014-04-07   538.15  1998-01-13  132.13
8     1998-01-14  19.75  2014-04-08   554.90  1998-01-14  131.13
9     1998-01-15  19.19  2014-04-09   564.14  1998-01-15  132.31
10    1998-01-16  18.81  2014-04-10   540.95  1998-01-16  135.25
11    1998-01-20  19.06  2014-04-11   530.60  1998-01-20  137.81
12    1998-01-21  18.91  2014-04-14   532.52  1998-01-21  137.00
13    1998-01-22  19.25  2014-04-15   536.44  1998-01-22  138.63
14    1998-01-23  19.50  2014-04-16   556.54  1998-01-23  138.25
15    1998-01-26  19.44  2014-04-17   536.10  1998-01-26  141.75

1) receiving_df необходимо установить общую основу для date (столбец уведомлений 2 отличается), поэтому DataFrame должен бытьорганизованы в date, 1, 3, 5, где даты 0, 2 и 4 используются для сборки date для правильного отражения значений в 1,3, 5 на определенную дату.

Пример вывода с шага 1:

               0      1       3       5
0     1998-01-02  16.25      NA  131.13
1     1998-01-05  15.88      NA  130.38
2     1998-01-06  18.94      NA  131.13
3     1998-01-07  17.50      NA  129.56
4     1998-01-08  18.19      NA  130.50
5     1998-01-09  18.19      NA  127.00
6     1998-01-12  18.25      NA  129.50
7     1998-01-13  19.50      NA  132.13
8     1998-01-14  19.75      NA  131.13
...
10    2014-04-10  18.81  558.46  135.25
11    2014-04-11  19.06  559.99  137.81
12    2014-04-14  18.91  556.97  137.00
13    2014-04-15  19.25  567.16  138.63
14    2014-04-16  19.50  567.00  138.25
15    2014-04-17  19.44  569.74  141.75
...

2) inserting_df необходимо отсортировать по дате в соответствии с receiving_df['date']и столбцы AAPL shares, GOOG shares, MSFT shares будут добавлены как столбцы в receiving_df.Я предполагаю, что это будет следовать тем же методам, что и в 1).

Пример вывода из шага 2:

               0   AAPL shares   1      GOOG shares       3   MSFT shares        5
0     1998-01-02           0.0   16.25          0.0       NA          0.0   131.13
1     1998-01-05           0.0   15.88          0.0       NA          0.0   130.38
2     1998-01-06           0.0   18.94          0.0       NA          0.0   131.13
3     1998-01-07           0.0   17.50          0.0       NA          0.0   129.56
4     1998-01-08           0.0   18.19          0.0       NA          0.0   130.50
5     1998-01-09           0.0   18.19          0.0       NA          0.0   127.00
6     1998-01-12           0.0   18.25          0.0       NA          0.0   129.50
7     1998-01-13           0.0   19.50          0.0       NA          0.0   132.13
8     1998-01-14           0.0   19.75          0.0       NA          0.0   131.13
...                                     
10    2014-04-10           0.0   18.81          0.0   558.46          0.0   135.25
11    2014-04-11           0.0   19.06          0.0   559.99          0.0   137.81
12    2014-04-14           0.0   18.91          0.0   556.97          0.0   137.00
13    2014-04-15           0.0   19.25          0.0   567.16          0.0   138.63
14    2014-04-16           0.0   19.50          0.0   567.00          0.0   138.25
15    2014-04-17           0.0   19.44          0.0   569.74          0.0   141.75
...            
<#>   2019-01-01           0.0   <value>       10.0   <value>         0.0   <value>  
<#>   2019-01-02           0.0   <value>        0.0   <value>        15.0   <value>
<#>   2019-01-03           0.0   <value>        0.0   <value>         7.0   <value>
<#>   2019-01-04           3.0   <value>        0.0   <value>         0.0   <value>
<#>   2019-01-05           0.0   <value>       -5.0   <value>         0.0   <value>

3) Новые столбцы AAPL shares, GOOG shares, MSFT shares будутнужно заполнить cumsum вперёд, но я думаю, что получил это: ~ df.set_index('date').sort_index().fillna(value=0).cumsum())

Пример вывода из шага 3:

               0   AAPL shares   1      GOOG shares       3   MSFT shares        5
0     1998-01-02           0.0   16.25          0.0       NA          0.0   131.13
1     1998-01-05           0.0   15.88          0.0       NA          0.0   130.38
2     1998-01-06           0.0   18.94          0.0       NA          0.0   131.13
3     1998-01-07           0.0   17.50          0.0       NA          0.0   129.56
4     1998-01-08           0.0   18.19          0.0       NA          0.0   130.50
5     1998-01-09           0.0   18.19          0.0       NA          0.0   127.00
6     1998-01-12           0.0   18.25          0.0       NA          0.0   129.50
7     1998-01-13           0.0   19.50          0.0       NA          0.0   132.13
8     1998-01-14           0.0   19.75          0.0       NA          0.0   131.13
...
10    2014-04-10           0.0   18.81          0.0   558.46          0.0   135.25
11    2014-04-11           0.0   19.06          0.0   559.99          0.0   137.81
12    2014-04-14           0.0   18.91          0.0   556.97          0.0   137.00
13    2014-04-15           0.0   19.25          0.0   567.16          0.0   138.63
14    2014-04-16           0.0   19.50          0.0   567.00          0.0   138.25
15    2014-04-17           0.0   19.44          0.0   569.74          0.0   141.75
...
<#>   2019-01-01           0.0   <value>       10.0   <value>         0.0   <value>
<#>   2019-01-02           0.0   <value>       10.0   <value>        15.0   <value>
<#>   2019-01-03           0.0   <value>       10.0   <value>        22.0   <value>
<#>   2019-01-04           3.0   <value>       10.0   <value>        22.0   <value>
<#>   2019-01-05           3.0   <value>        5.0   <value>        22.0   <value>

Таким образом, конечная цель приведет к значениям иакции держатся по индексу date.Для date, которые не будут иметь значения столбца 2 (поскольку в столбце 2 «отсутствуют» некоторые даты) в результирующем receiving_df, было бы лучше сделать это значение N/A, но 0 будетдостаточно.

Рад что-либо уточнить, я благодарен за любую помощь, поскольку это очень сложная операция (по крайней мере, для меня), заранее спасибо!

РЕДАКТИРОВАТЬ: Попытка объединить в петлю сейчас, так как количество пар date - value может варьироваться.Теперь у меня есть список отдельных DataFrames для пар date - value: dfs_list.Так как количество пар может варьироваться, лучше всего не set_index на основе меток столбцов, следовательно, set_index(rec_df.columns[0]).

rec_df = dfs_list[0].set_index(dfs_list[0].columns[0])
for dataframe in range(len(dfs_list)-1):
            rec_df = pd.merge(left=rec_df, right=dfs_list[dataframe+1].set_index(dfs_list[dataframe+1].columns[0]),
                              left_index=True, right_index=True,
                              how='outer')

1 Ответ

0 голосов
/ 18 февраля 2019

Исходя из ваших пояснений, вот что я понимаю, что такое решение.

Учитывая данные кадры, я добавил имена столбцов, чтобы сделать вещи более понятными, и переименовал receive_df в df, чтобы сохранитьпри наборе:

df.columns=['d1','p1','d2','p2','d3','p3']

df1=pd.merge(left=df[['d1','p1']].set_index('d1'),right=df[['d3','p3']].set_index('d3'), left_index=True, right_index=True, how='outer')

df1.head()

            p1      p3
d1      
1998-01-02  16.25   131.13
1998-01-05  15.88   130.38
1998-01-06  18.94   131.13
1998-01-07  17.50   129.56
1998-01-08  18.19   130.50

rec_df=pd.merge(left=df1,right=df[['d2','p2']].set_index('d2'),left_index=True, right_index=True, how='outer')

rec_df

            p1      p3      p2
1998-01-02  16.25   131.13  NaN
1998-01-05  15.88   130.38  NaN
1998-01-06  18.94   131.13  NaN
1998-01-07  17.50   129.56  NaN
1998-01-08  18.19   130.50  NaN
1998-01-09  18.19   127.00  NaN
1998-01-12  18.25   129.50  NaN
1998-01-13  19.50   132.13  NaN
1998-01-14  19.75   131.13  NaN
1998-01-15  19.19   132.31  NaN
1998-01-16  18.81   135.25  NaN
1998-01-20  19.06   137.81  NaN
1998-01-21  18.91   137.00  NaN
1998-01-22  19.25   138.63  NaN
1998-01-23  19.50   138.25  NaN
1998-01-26  19.44   141.75  NaN
2014-03-27  NaN NaN 558.46
2014-03-28  NaN NaN 559.99
2014-03-31  NaN NaN 556.97
2014-04-01  NaN NaN 567.16
2014-04-02  NaN NaN 567.00
2014-04-03  NaN NaN 569.74
2014-04-04  NaN NaN 543.14
2014-04-07  NaN NaN 538.15
2014-04-08  NaN NaN 554.90
2014-04-09  NaN NaN 564.14
2014-04-10  NaN NaN 540.95
2014-04-11  NaN NaN 530.60
2014-04-14  NaN NaN 532.52
2014-04-15  NaN NaN 536.44
2014-04-16  NaN NaN 556.54
2014-04-17  NaN NaN 536.10

Теперь я не смог протестировать, поскольку у вашей вставки df нет совпадающих индексов даты из полученной df, но должно выглядеть как

final_df=pd.merge(left=rec_df, right=insert_df, left_index=True, right_index=True, dropna=False)

Конечно, это предполагает, что столбец date уже установлен в качестве индекса, как в вашем примере.Если вам нужен числовой индекс в конце, вы можете reset_index(in_place=True), или вы можете оставить дату в качестве индекса.

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

И учтите также, что вы можете изменить порядок столбцов так, как вы хотите, в зависимости от того, как вы хотите, чтобы ваш вывод выглядел (df=df[[list of columns in order]])

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...