Фрейм данных Pandas Преобразование данных в длинном формате в широкоформатный для определенного диапазона дат - PullRequest
0 голосов
/ 23 февраля 2019

Я пытаюсь преобразовать данные временного ряда из длинного в широкий формат.Ниже приведены данные:

+======+==========+======+======+
| Name |   Date   | Val1 | Val2 |
+======+==========+======+======+
| A    | 1/1/2018 |    1 |    2 |
+------+----------+------+------+
| B    | 1/1/2018 |    2 |    3 |
+------+----------+------+------+
| C    | 1/1/2018 |    3 |    4 |
+------+----------+------+------+
| D    | 1/4/2018 |    4 |    5 |
+------+----------+------+------+
| A    | 1/4/2018 |    5 |    6 |
+------+----------+------+------+
| B    | 1/4/2018 |    6 |    7 |
+------+----------+------+------+
| C    | 1/4/2018 |    7 |    8 |
+------+----------+------+------+

Моя конечная цель - создать сводную таблицу для диапазона дат от 01/01/2018 до 01/04/2018.Поскольку даты с датами 01/02/2018 или 01/03/2018 не имеют значения, я ожидаю, что они будут заполнены NaN.Для большей простоты мой итоговый стол будет выглядеть так:

+---+---------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+
|   | Val1.1/1/2018 | Val2.1/1/2018 | Val1.1/2/2018 | Val2.1/2/2018 | Val1.1/3/2018 | Val2.1/3/2018 | Val1.1/4/2018 | Val2.1/4/2018 |
+---+---------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+
| A | 1             | 2             | NULL          | NULL          | NULL          | NULL          |             5 |             6 |
| B | 2             | 3             | NULL          | NULL          | NULL          | NULL          |             6 |             7 |
| C | 3             | 4             | NULL          | NULL          | NULL          | NULL          |             7 |             8 |
| D | NULL          | NULL          | NULL          | NULL          | NULL          | NULL          |             4 |             5 |
+---+---------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+

В соответствии с моим пониманием, чтобы перейти выше таблицы, есть два шага.Во-первых, заполнить данные в длинном формате датами, которых нет в диапазоне от 01/01/2018 до 01/04/2018, то есть равно 01/02/2018 и 01/03/2018.

Вторым и последним шагом будет развернуть данные в широком диапазоне.формат.

Для достижения первого шага я сослался на этот пост .Согласно ответу, если в нескольких строках есть похожие даты, df.reindex(date_range) вызовет следующую ошибку, ValueError: cannot reindex from a duplicate axis, которая является истинной, и чтобы преодолеть это, я следовал следующему куску кода.

df['Date'] =  pd.to_datetime(df['Date'], format='%m/%d/%Y')
df.set_index('Date', inplace = True)

date_range = pd.date_range('2018-01-01', '2018-01-04', freq='D')
df = df.loc(date_range)

Приведенный выше кодвыдает мне следующую ошибку:

TypeError: unhashable type: 'DatetimeIndex'

Я решил вышеупомянутую проблему, используя эту строку кода

df = df.loc[date_range,:]

Хотя я могу получить желаемый длинный формат, но Python выдает предупреждениеследующим образом:

Passing list-likes to .loc or [] with any missing label will raise
KeyError in the future, you can use .reindex() as an alternative.

Вышеприведенное предупреждение, как мне кажется, говорит о том, что мой способ получения таблицы длинного формата с отсутствующими датами неверен, верно?Если да, то как мне это сделать?Кроме того, как мне добраться до широкоформатной таблицы, которую я хочу использовать в качестве финальной таблицы?

Редактировать: Я достиг сводной таблицы, содержащей только даты '01/01/2018' и '01/04/2018'.Ниже приведен фрагмент кода.

df1 = df.pivot_table(index='Name', columns='Date', aggfunc='sum')

1 Ответ

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

Сначала переиндексируйте Dataframe, чтобы добавить пропущенные даты.Затем поверните и объедините столбцы.

idx = pd.MultiIndex.from_product([df.Name.unique(), pd.date_range(df.Date.min(), df.Date.max())])

df = df.set_index(['Name','Date']).reindex(idx).reset_index().rename(columns = {'level_0':'Name', 'level_1':'Date'})

df.Date = df.Date.dt.strftime('%m/%d/%Y')
new_df = df.pivot('Name', 'Date', ['Val1', 'Val2'])
new_df.columns = new_df.columns.map('.'.join)

    Val1.01/01/2018 Val1.01/02/2018 Val1.01/03/2018 Val1.01/04/2018 Val2.01/01/2018 Val2.01/02/2018 Val2.01/03/2018 Val2.01/04/2018
Name                                
A   1.0             NaN             NaN              5.0            2.0 NaN NaN 6.0
B   2.0             NaN             NaN              6.0            3.0 NaN NaN 7.0
C   3.0             NaN             NaN              7.0            4.0 NaN NaN 8.0
D   NaN             NaN             NaN              4.0            NaN NaN NaN 5.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...