我正在处理一个数据框,其中包含跨越几年的每小时温度数据的日期时间索引。我想添加一个最低温度在一天的 20:00 到第二天的 8:00 之间的列。白天的温度 - 从8:00到20:00 - 不感兴趣。结果可以与原始数据每小时分辨率相同,也可以重新采样为天。
我已经研究了许多策略来解决这个问题,但不确定最有效的方法(在主要编码效率和辅助计算效率方面)分别是pythonic方法。我想出的一些可能性:
- 根据
df.index.hour
附加带有标签"白天"、"夜晚"的列,并使用group_by
或df.loc
来查找最小值 - 重新采样到 12 小时并每秒删除一次值。不知道我怎样才能使重新采样期从 20:00 开始。
- 添加一个多索引 - 我想这类似于方法 1,但对于我想要实现的目标来说感觉有点过头了。
- 使用
df.between_time
(https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.between_time.html#pandas.DataFrame.between_time),尽管我不确定午夜的日期更改是否会使这有点混乱。 - 最后,有一些关于将滚动与步进参数组合为新的熊猫功能的讨论:https://github.com/pandas-dev/pandas/issues/15354
原始 df 如下所示:
datetime temp
2009-07-01 01:00:00 17.16
2009-07-01 02:00:00 16.64
2009-07-01 03:00:00 16.21 #<-- minimum for the night 2009-06-30 (previous date since periods starts 2009-06-30 20:00)
... ...
2019-06-24 22:00:00 14.03 #<-- minimum for the night 2019-06-24
2019-06-24 23:00:00 18.87
2019-06-25 00:00:00 17.85
2019-06-25 01:00:00 17.25
我想得到这样的东西(从第 20:00 天到第 +1 天 8:00 的最低温度):
datetime temp
2009-06-30 23:00:00 16.21
2009-07-01 00:00:00 16.21
2009-07-01 01:00:00 16.21
2009-07-01 02:00:00 16.21
2009-07-01 03:00:00 16.21
... ...
2019-06-24 22:00:00 14.03
2019-06-24 23:00:00 14.03
2019-06-25 00:00:00 14.03
2019-06-25 01:00:00 14.03
或者更简洁一点:
datetime temp
2009-06-30 16.21
... ...
2019-06-24 14.03
使用base
选项resample
:
rs = df.resample('12h', base=8).min()
然后只保留 20:00 的行:
rs[rs.index.hour == 20]
您可以将TimeGrouper
与freq=12h
一起使用,base=8
从20:00 - (+day)08:00每12小时对数据帧进行分块,
然后你可以只使用.min()
试试这个:
import pandas as pd
from io import StringIO
s = """
datetime temp
2009-07-01 01:00:00 17.16
2009-07-01 02:00:00 16.64
2009-07-01 03:00:00 16.21
2019-06-24 22:00:00 14.03
2019-06-24 23:00:00 18.87
2019-06-25 00:00:00 17.85
2019-06-25 01:00:00 17.25"""
df = pd.read_csv(StringIO(s), sep="ss+")
df['datetime'] = pd.to_datetime(df['datetime'])
result = df.sort_values('datetime').groupby(pd.Grouper(freq='12h', base=8, key='datetime')).min()['temp'].dropna()
print(result)
输出:
datetime
2009-06-30 20:00:00 16.21
2019-06-24 20:00:00 14.03
Name: temp, dtype: float64