为什么在根据时间序列数据进行分位数计算时会得到意外的非零值?

Why do I get unexpected nonzero values when doing a quantiles calculation from timeseries data?

我有一个 csv 文件,其中包含全年每小时光伏生产的时间序列数据。我想获得每小时的分位数(从 0.1 到 0.9),以便在一年中的所有日子里每 24 小时代表他们的行为。

起初似乎工作正常,但后来我意识到在我的一些分位数中我的值在 00:00 处不同于零 (0),这是不可能的,因为我的数据集没有这样的值在一天中的那个时候(我检查了三次)。

哪里错了?

我的代码:

colnames = ['Date', 'Energy']
df_1 = pd.read_csv('PV_Autumn_2020.csv', names = colnames  , encoding="utf8", delimiter=";")

start_date = datetime(2022, 9, 27, 1, 0)
end_date = datetime(2022, 9, 28, 1, 0)

def daterange(start_date, end_date):
    delta = timedelta(hours=1)
    while start_date < end_date:
        yield start_date
        start_date += delta
        
df = pd.DataFrame(columns = ['Time','pct0.1','pct0.2','pct0.3','pct0.4','pct0.5','pct0.6','pct0.7','pct0.8','pct0.9'])

for single_date in daterange(start_date, end_date):
            df.loc[single_date, ['Time']] = single_date.strftime("%H:%M")


x = []

for index in df.index:
    y = df_1.loc[df_1['Date'].str.contains(df['Time'][index])]
    for i in np.arange(1, 10, 1)/10:
        x.append(y.quantile(i))

pct = pd.DataFrame(x, columns = ['Energy'])

df['pct0.1'] = pct.loc[0.1].values
df['pct0.2'] = pct.loc[0.2].values
df['pct0.3'] = pct.loc[0.3].values
df['pct0.4'] = pct.loc[0.4].values
df['pct0.5'] = pct.loc[0.5].values
df['pct0.6'] = pct.loc[0.6].values
df['pct0.7'] = pct.loc[0.7].values
df['pct0.8'] = pct.loc[0.8].values
df['pct0.9'] = pct.loc[0.9].values

csv文件的一部分:

2021/03/01 00:00:00;0
2021/03/01 01:00:00;0
2021/03/01 02:00:00;0
2021/03/01 03:00:00;0
2021/03/01 04:00:00;0
2021/03/01 05:00:00;0
2021/03/01 06:00:00;0
2021/03/01 07:00:00;0
2021/03/01 08:00:00;111
2021/03/01 09:00:00;609
2021/03/01 10:00:00;1152
2021/03/01 11:00:00;1596
2021/03/01 12:00:00;1919
2021/03/01 13:00:00;2062
2021/03/01 14:00:00;2003
2021/03/01 15:00:00;1755
2021/03/01 16:00:00;1351
2021/03/01 17:00:00;801
2021/03/01 18:00:00;233
2021/03/01 19:00:00;0
2021/03/01 20:00:00;0
2021/03/01 21:00:00;0
2021/03/01 22:00:00;0
2021/03/01 23:00:00;0
2021/03/02 00:00:00;0
2021/03/02 01:00:00;0
2021/03/02 02:00:00;0
2021/03/02 03:00:00;0
2021/03/02 04:00:00;0
2021/03/02 05:00:00;0
2021/03/02 06:00:00;0
2021/03/02 07:00:00;0
2021/03/02 08:00:00;92
2021/03/02 09:00:00;449
2021/03/02 10:00:00;905
2021/03/02 11:00:00;1387
2021/03/02 12:00:00;1516
2021/03/02 13:00:00;1617
2021/03/02 14:00:00;1671
2021/03/02 15:00:00;1525
2021/03/02 16:00:00;1290
2021/03/02 17:00:00;899
2021/03/02 18:00:00;312
2021/03/02 19:00:00;0
2021/03/02 20:00:00;0
2021/03/02 21:00:00;0
2021/03/02 22:00:00;0
2021/03/02 23:00:00;0

创建的数据框

    Time    pct0.1  pct0.2  pct0.3  pct0.4  pct0.5  pct0.6  pct0.7  pct0.8  pct0.9
2022-09-27 01:00:00 01:00   0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2022-09-27 02:00:00 02:00   0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2022-09-27 03:00:00 03:00   0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2022-09-27 04:00:00 04:00   0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2022-09-27 05:00:00 05:00   0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2022-09-27 06:00:00 06:00   0.0 0.0 0.0 1.0 4.0 13.0    24.0    39.0    56.0
2022-09-27 07:00:00 07:00   25.0    51.0    84.0    148.0   180.0   249.0   297.0   378.0   426.0
2022-09-27 08:00:00 08:00   271.0   374.0   444.0   540.0   632.0   763.0   843.0   885.0   969.0
2022-09-27 09:00:00 09:00   545.0   743.0   880.0   1012.0  1079.0  1182.0  1285.0  1359.0  1401.0
2022-09-27 10:00:00 10:00   754.0   1037.0  1184.0  1315.0  1392.0  1478.0  1574.0  1654.0  1700.0
2022-09-27 11:00:00 11:00   858.0   1155.0  1291.0  1454.0  1540.0  1612.0  1695.0  1800.0  1853.0
2022-09-27 12:00:00 12:00   866.0   1185.0  1333.0  1452.0  1545.0  1630.0  1721.0  1820.0  1893.0
2022-09-27 13:00:00 13:00   871.0   1069.0  1239.0  1350.0  1435.0  1521.0  1612.0  1715.0  1817.0
2022-09-27 14:00:00 14:00   673.0   943.0   1036.0  1112.0  1207.0  1318.0  1383.0  1484.0  1622.0
2022-09-27 15:00:00 15:00   420.0   590.0   689.0   743.0   805.0   989.0   1045.0  1163.0  1297.0
2022-09-27 16:00:00 16:00   130.0   184.0   222.0   304.0   385.0   487.0   603.0   682.0   855.0
2022-09-27 17:00:00 17:00   1.0 3.0 7.0 30.0    55.0    96.0    152.0   207.0   338.0
2022-09-27 18:00:00 18:00   0.0 0.0 0.0 0.0 0.0 2.0 4.0 11.0    31.0
2022-09-27 19:00:00 19:00   0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2022-09-27 20:00:00 20:00   0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2022-09-27 21:00:00 21:00   0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2022-09-27 22:00:00 22:00   0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2022-09-27 23:00:00 23:00   0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2022-09-28 00:00:00 00:00   0.0 0.0 0.0 0.0 5.0 163.0   626.1   1059.0  1439.7

您通过测试相关时间字符串是输入数据中日期字符串的一部分来计算分位数。日期字符串由年、月、日、小时、分钟和秒组成。但是,时间字符串仅包含小时和分钟。输入日期的所有秒数都设置为零,您的输入日期时间戳就像“01:00:00”、“02:00:00”等。这很好,但是当比较字符串时(与 in),比较时间字符串“00:00”有问题:它适合 all 日期字符串:它只需将小时和分钟与分钟和秒匹配。例如,"00:00" is in "02:00:00" 的计算结果为 True。因此,所有(?)输入数据都将添加到“00:00”时间戳,而不是没有输入数据。

因此,一个简单的解决方案是将比较时间增加几秒:

for single_date in daterange(start_date, end_date):
    df.loc[single_date, ['Time']] = single_date.strftime("%H:%M:%S")

当然,比较时间戳与日期戳或计算分位数可能有更好的方法,但这似乎是您当前问题背后的实际问题。