pandas:重新采样并计算正确的均值

问题描述 投票:0回答:1

我正在使用python的熊猫,但我不知道如何使用梯形规则将时间序列重新采样为1分钟分辨率并计算每个间隔的平均值。

假设我们在文件data.csv中给出了以下时间序列:

time_stamp,x
2000-01-01 00:00:00,0.0
2000-01-01 00:00:10,100.0
2000-01-01 00:02:00,100.0
2000-01-01 00:03:00,200.0

请注意,在第一分钟的大部分时间内,x值等于100,因此答案

2000-01-01 00:00:00: 50.0,
2000-01-01 00:01:00: nan,
2000-01-01 00:02:00: 100.0,
2000-01-01 00:03:00: 200.0

获得者

pd.read_csv("data.csv", index_col="time_stamp", parse_dates=["time_stamp"]).resample("1min").mean()

是错误的。第一分钟的正确平均值是91.66666 = [(0 + 100) / 2 * 10s + 100 * 50s)] / 60s。同样,时间间隔[2:00, 3:00]的答案应为150

python-3.x pandas mean resampling
1个回答
0
投票

数据问题是不相等的时间步长。

import pandas as pd

# Create your dataset
index = pd.date_range('2000/01/01  00:00:00', periods=4, freq='min').to_list()
index[1] = pd.Timestamp('2000/01/01  00:00:10')
values = [0., 100., 100., 200.]

data = pd.Series(values, index)
data

[Out]: 
2000-01-01 00:00:00      0.0
2000-01-01 00:00:10    100.0
2000-01-01 00:02:00    100.0
2000-01-01 00:03:00    200.0

当您打电话给.resample()时,这是正在发生的事情:

data.asfreq('T')
[Out]:
2000-01-01 00:00:00      0.0
2000-01-01 00:01:00      NaN
2000-01-01 00:02:00    100.0
2000-01-01 00:03:00    200.0

将值放入其对应的分钟中,因为在1分钟至2分钟之间没有数据,所以该值用NaN填充。 .mean()没有做任何有用的事情(它将生成器对象转换为df / series)。

您可以重新采样到10秒,向前填充,然后重新采样到1分钟。

print(data.resample('10s').ffill())

[Out]:
2000-01-01 00:00:00      0.0
2000-01-01 00:00:10    100.0
2000-01-01 00:00:20    100.0
2000-01-01 00:00:30    100.0
2000-01-01 00:00:40    100.0
2000-01-01 00:00:50    100.0
2000-01-01 00:01:00    100.0
2000-01-01 00:01:10    100.0
2000-01-01 00:01:20    100.0
2000-01-01 00:01:30    100.0
2000-01-01 00:01:40    100.0
2000-01-01 00:01:50    100.0
2000-01-01 00:02:00    100.0
2000-01-01 00:02:10    100.0
2000-01-01 00:02:20    100.0
2000-01-01 00:02:30    100.0
2000-01-01 00:02:40    100.0
2000-01-01 00:02:50    100.0
2000-01-01 00:03:00    200.0

print(data.resample('10s').ffill().resample('1t').mean())
[Out]:
2000-01-01 00:00:00     83.333333
2000-01-01 00:01:00    100.000000
2000-01-01 00:02:00    100.000000
2000-01-01 00:03:00    200.000000

在您的问题中,您希望2分钟至3分钟之间的结果为150,但事实并非如此,因为您在这一分钟的整个时间内的值为100。

也许您会发现.interpolate(method='time')有用。 Here's a link to the docs

© www.soinside.com 2019 - 2024. All rights reserved.