У меня есть pandas dataframe (без индекса) с неуклюжим расположением, которое выглядит примерно так, но длиной около 60000 строк:
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
Первый столбец - ГГГГММДД, а второй - час. Я хочу сделать из них один 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»).
Попытка выполнить 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 )
edit: мне нужно добавить ведущий 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)