【问题标题】:Reindexing timeseries data索引时间序列数据
【发布时间】:2020-02-14 13:32:32
【问题描述】:

我有一个类似于"ValueError: cannot reindex from a duplicate axis" 的问题。没有提供解决方案。

我有一个包含多行多列天气数据的 excel 文件。尽管下面的示例中未显示数据,但在某些时间间隔内缺少数据。我想每隔 5 分钟重新索引时间列,以便可以插入缺失值。数据样本:


Date        Time    Temp    Hum Dewpnt  WindSpd
04/01/18    12:05 a 30.6    49  18.7    2.7
04/01/18    12:10 a NaN     51  19.3    1.3
04/01/18    12:20 a 30.7   NaN  19.1    2.2
04/01/18    12:30 a 30.7    51  19.4    2.2 
04/01/18    12:40 a 30.9    51  19.6    0.9

这是我尝试过的。

import pandas as pd
ts = pd.read_excel('E:\DATA\AP.xlsx')
ts['Time'] = pd.to_datetime(ts['Time'])
ts.set_index('Time', inplace=True)
dt = pd.date_range("2018-04-01 00:00:00", "2018-05-01 00:00:00", freq='5min', name='T')
idx = pd.DatetimeIndex(dt)
ts.reindex(idx)

我只想让我的索引以 5 分钟的频率出现,以便稍后插入 NaN。 预期输出:

Date        Time    Temp    Hum Dewpnt  WindSpd
04/01/18    12:05 a 30.6    49  18.7    2.7
04/01/18    12:10 a NaN     51  19.3    1.3
04/01/18    12:15 a NaN   NaN  NaN     NaN
04/01/18    12:20 a 30.7   NaN  19.1    2.2
04/01/18    12:25 a NaN   NaN  NaN     NaN
04/01/18    12:30 a 30.7    51  19.4    2.2  

【问题讨论】:

  • 以文本而非图片的形式提供您的输入数据和预期输出。
  • 进行了建议的更改。

标签: python pandas time-series python-datetime reindex


【解决方案1】:

另一种方法。

df['Time'] = pd.to_datetime(df['Time'])
df = df.set_index(['Time']).resample('5min').last().reset_index()
df['Time'] = df['Time'].dt.time
df

输出

       Time     Date        Temp    Hum     Dewpnt  WindSpd
0   00:05:00    4/1/2018    30.6    49.0    18.7    2.7
1   00:10:00    4/1/2018    NaN     51.0    19.3    1.3
2   00:15:00    NaN         NaN     NaN     NaN     NaN
3   00:20:00    4/1/2018    30.7    NaN     19.1    2.2
4   00:25:00    NaN         NaN     NaN     NaN     NaN
5   00:30:00    4/1/2018    30.7    51.0    19.4    2.2
6   00:35:00    NaN         NaN     NaN     NaN     NaN
7   00:40:00    4/1/2018    30.9    51.0    19.6    0.9

如果必须重新采样多个日期的时间,您可以使用下面的代码。

但是,稍后您必须将“日期”和“时间”列分开。

df1['DateTime'] = df1['Date']+df1['Time']
df1['DateTime'] = pd.to_datetime(df1['DateTime'],format='%d/%m/%Y%I:%M %p')
df1 = df1.set_index(['DateTime']).resample('5min').last().reset_index()
df1

输出

DateTime    Date    Time    Temp    Hum     Dewpnt  WindSpd
0   2018-01-04 00:05:00     4/1/2018    12:05 AM    30.6    49.0    18.7    2.7
1   2018-01-04 00:10:00     4/1/2018    12:10 AM    NaN     51.0    19.3    1.3
2   2018-01-04 00:15:00     NaN     NaN     NaN     NaN     NaN     NaN
3   2018-01-04 00:20:00     4/1/2018    12:20 AM    30.7    NaN     19.1    2.2
4   2018-01-04 00:25:00     NaN     NaN     NaN     NaN     NaN     NaN
5   2018-01-04 00:30:00     4/1/2018    12:30 AM    30.7    51.0    19.4    2.2
6   2018-01-04 00:35:00     NaN     NaN     NaN     NaN     NaN     NaN
7   2018-01-04 00:40:00     4/1/2018    12:40 AM    30.9    51.0    19.6    0.9

【讨论】:

  • 它正在工作,但输出似乎只有最后 1 天的数据(4 月的最后一天)。如何修改它以包含整个数据集?我认为日期和时间列都需要合并。
  • 我已经让它与您的回答中的有用建议一起工作。添加了工作代码。
【解决方案2】:

你可以试试这个例子:

import pandas as pd
ts = pd.read_excel('E:\DATA\AP.xlsx')
ts['Time'] = pd.to_datetime(ts['Time'])
ts.set_index('Time', inplace=True)
ts.resample('5T').mean()

更多信息在这里:https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.resample.html

【讨论】:

  • 不幸的是,它没有用。我没有收到错误,但数据集没有被重新采样,因为输出与输入相同。
  • ts.interpolate(method='linear', inplace=True)
  • 输出没有新间隔的值。
【解决方案3】:

将Time列设置为索引,确保是DateTime类型,然后尝试

ts.asfreq('5T')

使用

ts.asfreq('5T', method='ffill')

将先前的值向前拉。

【讨论】:

  • 我已经将“时间”作为索引和日期时间类型。我遇到了和以前一样的错误。
【解决方案4】:

我会采取创建一个空白表的方法,并用来自您的数据源的数据填充它。对于此示例,三个观察值被读入为 NaN,加上 1:15 和 1:20 的行缺失。

import pandas as pd
import numpy as np
rawpd = pd.read_excel('raw.xlsx')
print(rawpd)
    Date      Time  Col1  Col2

0 2018-04-01 01:00:00 1.0 10.0
1 2018-04-01 01:05:00 2.0 NaN
2 2018-04-01 01:10:00 NaN 10.0
3 2018-04-01 01:20:00 NaN 10.0
4 2018-04-01 01:30:00 5.0 10.0

现在创建一个具有理想结构的数据框 targpd。

time5min = pd.date_range(start='2018/04/1 01:00',periods=7,freq='5min')
targpd = pd.DataFrame(np.nan,index = time5min,columns=['Col1','Col2'])
print(targpd)

                 Col1  Col2 

2018-04-01 01:00:00 NaN NaN
2018-04-01 01:05:00 NaN NaN
2018-04-01 01:10:00 NaN NaN
2018-04-01 01:15:00 NaN NaN
2018-04-01 01:20:00 NaN NaN
2018-04-01 01:25:00 NaN NaN
2018-04-01 01:30:00 NaN NaN

现在的诀窍是用 rawpd 中发送给您的数据更新 targpd。为此,必须在 rawpd 中将日期和时间列组合并制成索引。

print(rawpd.Date,rawpd.Time)

0 2018-04-01
1 2018-04-01
2 2018-04-01
3 2018-04-01
4 2018-04-01

名称:日期,数据类型:datetime64[ns]
0 01:00:00
1 01:05:00
2 01:10:00
3 01:20:00
4 01:30:00
名称:时间,数据类型:对象
您可以在所有这些中看到上面的技巧。您的日期数据已转换为日期时间,但您的时间数据只是一个字符串。使用 lambda 函数可以创建低于适当索引的索引。

rawidx=rawpd.apply(lambda r : pd.datetime.combine(r['Date'],r['Time']),1)
print(rawidx)

这可以作为索引应用于 rawpd 数据库。

rawpd2=pd.DataFrame(rawpd[['Col1','Col2']].values,index=rawidx,columns=['Col1','Col2'])
rawpd2=rawpd2.sort_index()
print(rawpd2)

一旦完成,更新命令就可以得到你想要的。

targpd.update(rawpd2,overwrite=True)
print(targpd)

                 Col1  Col2

2018-04-01 01:00:00 1.0 10.0

2018-04-01 01:00:00 1.0 10.0

2018-04-01 01:05:00 2.0 NaN

2018-04-01 01:10:00 NaN 10.0

2018-04-01 01:15:00 NaN NaN

2018-04-01 01:20:00 NaN 10.0

2018-04-01 01:25:00 NaN NaN

2018-04-01 01:30:00 5.0 10.0

2018-04-01 01:05:00 2.0 NaN

2018-04-01 01:10:00 NaN 10.0

2018-04-01 01:15:00 NaN NaN

2018-04-01 01:20:00 NaN 10.0

2018-04-01 01:25:00 NaN NaN

2018-04-01 01:30:00 5.0 10.0

您现在已经准备好进行插值的文件

【讨论】:

  • 您好,我在运行 rawpd2 时遇到此错误。 KeyError:“[Index(['Col1', 'Col2'], dtype='object')] 都没有在 [columns] 中”,在那之前一切都很好。
  • lambda 函数可能很难调试。我会寻找像“col1”与“Col1”这样的错字
【解决方案5】:

我已经让它工作了。谢谢大家的时间。我正在提供工作代码。

import pandas as pd
df = pd.read_excel('E:\DATA\AP.xlsx', sheet_name='Sheet1', parse_dates=[['Date', 'Time']])
df = df.set_index(['Date_Time']).resample('5min').last().reset_index()
print(df)

【讨论】:

    猜你喜欢
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多