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

时间:2018-09-04 15:01:35

标签: python-3.x pandas dataframe datetime-format

我有一个熊猫数据框(没有索引),排列看起来很笨拙,但是长约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,并且日期需要增加一个。它需要在月份和年份的末尾工作(在“ 20111231 24”的情况下,日期,月份和年份都需要增加)。

尝试执行dates.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

edit:我必须自己添加前导0,因为我无法让%-H用作参数,显然它不适用于所有后端,并且与这个好人{{3} }

(如果您正在使用源数据,则可能会发现这很有用):

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)

1 个答案:

答案 0 :(得分:1)

您可以按照以下几个步骤进行操作:

  • 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)