使用 Pandas 数据框将长格式数据转换为特定日期范围的宽格式数据

3

我正在尝试将一系列的时间序列数据从长格式转换为宽格式。以下是所给的数据。

+======+==========+======+======+
| 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 |
+------+----------+------+------+

我的最终目标是创建一个数据透视表,日期范围为2018年1月1日2018年1月4日。由于在2018年1月2日2018年1月3日这些日期没有值,我期望它们会被填充为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/201801/04/2018之间的范围内,即01/02/201801/03/2018
第二步也是最后一步,将数据透视为宽格式。
为了实现第一步,我参考了这篇post。根据答案,如果多行中存在相似的日期,则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个回答

1

首先重新索引数据框以添加缺失的日期。然后进行透视并合并列。

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

在代码行 new_df = df.pivot('Name', 'Date', ['Val1', 'Val2']) 处出现了错误,错误信息为 Exception: Data must be 1-dimensional - Furqan Hashim
你的数据集中有更多的列吗? - Vaishali
以下是 df.columns 的结果,Index(['Name', 'Date', 'Val1', 'Val2'], dtype='object') - Furqan Hashim
将我的Python版本从3.5.x更改为3.6.5后,错误得到了解决。 - Furqan Hashim
发现我读取的数据文件没有解析日期,经过解析后运行您的代码,我成功得到了想要的表格。 - Furqan Hashim
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接