熊猫多个数据帧列到单个日期时间索引



我有一个熊猫数据帧(没有索引(,其排列很尴尬,看起来像这样,但大约有 60,000 行长:

YYYYMMDD,   HH, DATA
20110101,    1,  220
20110101,    2,  220
20110101,    3,  220
20110101,    4,  230
20110101,    5,  230
20110101,    6,  220
20110101,    7,  240
20110101,    8,  230
20110101,    9,  230
20110101,   10,  230
20110101,   11,  240
20110101,   12,  230
20110101,   13,  240
20110101,   14,  240
20110101,   15,  260
20110101,   16,  270
20110101,   17,  280
20110101,   18,  300
20110101,   19,  300
20110101,   20,  320
20110101,   21,  310
20110101,   22,  310
20110101,   23,  310
20110101,   24,  300
20110102,    1,  290
20110102,    2,  270

第一列是YYYYMMDD,第二列是小时。我想从中制作一个 pd.datetimeindex,但存在一些问题。

与 HH标题相反,HH 数据没有前导零,并且诸如"20110101,24"之类的日期时间实际上应该读作"20110102, 00"以使pd.to_datetime正常工作,即您不应该有一个小时是 24,如果是 24,它应该是 00 并且日期递增。

我目前已经走到了这一步:

f = lambda x: pd.to_datetime(x, format='%Y%m%d %H', exact=False)
df = pd.read_csv(path)
dates = df.YYYYMMDD.apply(lambda x: str(x)+' ') 
+ df.HH.apply(lambda x: '0'+str(x) if len(str(x))==1 else str(x))
dates.apply(f)

第三行创建一个组合两列并在必要时添加前导零的序列,但我无法优雅地处理 24 小时需要更改为 00 并且日期需要增加 1 的边缘情况。它需要在月底和年底工作(在"20111231 24"的情况下,日期、月份和年份都需要增加(。

尝试执行 date.apply(f( 会给出预期错误,即 24 是意外的:

ValueError: time data '20110101 24' doesn't match format specified

有人知道优雅地做到这一点的方法吗?我想要一列类型为 pandas._libs.tslib.Timestamp 的列,我可以轻松地将其转换为索引。

非常感谢。使用 Python 3.6,您可以在此处找到源数据:https://cdn.knmi.nl/knmi/map/page/klimatologie/gegevens/uurgegevens/uurgeg_380_2011-2020.zip(来自本网站 www.knmi.nl(

编辑:我必须自己添加前导 0,因为我无法让 %-H 用作参数。显然它不适用于所有后端,在这里遇到与这个好人相同的错误

(如果您使用的是源数据,您可能会发现这很有用(:

path = '/uurgeg_380_2011-2020.txt'
header_row = pd.read_csv(path, sep=",", skiprows=31, nrows=0).columns.values
header_row = np.array([x.replace(' ','').replace('#','') for x in header_row])
f = lambda x: pd.to_datetime(x, format='%Y%m%d %H', exact=False)
df = pd.read_csv(path, skiprows=32, names=header_row)
dates = df.YYYYMMDD.apply(lambda x: str(x)+' ') 
+ df.HH.apply(lambda x: '0'+str(x) if len(str(x))==1 else str(x))
dates.apply(f)

您可以通过几个步骤执行此操作:

  • YYYYMMDD更改为日期时间(仅日期(
  • 24条目添加一天(使用Timedelta(
  • 24更改为零
  • 零填充HH列(作为字符串类型,使用zfill(
  • 创建日期时间列:

喜欢这个:

df['YYYYMMDD'] = pd.to_datetime(df.YYYYMMDD, format='%Y%m%d')
df.loc[df.HH == 24, 'YYYYMMDD'] += pd.Timedelta(days=1)
df.loc[df.HH == 24, 'HH'] = 0
df['HH'] = df.HH.astype(str).str.zfill(2)
df.index = pd.to_datetime(df['YYYYMMDD'].astype(str) + ' ' + df['HH'],
format='%Y-%m-%d %H')

然后,您可以查看新创建的索引:

>>> df.index
DatetimeIndex(['2011-01-01 01:00:00', '2011-01-01 02:00:00',
'2011-01-01 03:00:00', '2011-01-01 04:00:00',
'2011-01-01 05:00:00', '2011-01-01 06:00:00',
'2011-01-01 07:00:00', '2011-01-01 08:00:00',
'2011-01-01 09:00:00', '2011-01-01 10:00:00',
'2011-01-01 11:00:00', '2011-01-01 12:00:00',
'2011-01-01 13:00:00', '2011-01-01 14:00:00',
'2011-01-01 15:00:00', '2011-01-01 16:00:00',
'2011-01-01 17:00:00', '2011-01-01 18:00:00',
'2011-01-01 19:00:00', '2011-01-01 20:00:00',
'2011-01-01 21:00:00', '2011-01-01 22:00:00',
'2011-01-01 23:00:00', '2011-01-02 00:00:00',
'2011-01-02 01:00:00', '2011-01-02 02:00:00'],
dtype='datetime64[ns]', freq=None)

最新更新