У меня есть набор данных временных рядов с индексом в виде даты и времени (почти 1 строка на каждый день года), я хочу время от времени создавать разреженные ряды (для построения графиков) со строкой.
obs_date str_date
2018-01-01 Jan 2018
2018-01-02
2018-01-03
2018-01-04
2018-01-05
2018-01-06
...
2018-02-01 Feb 2018
etc
я пытался
df['str_date'] = df.index.strftime('%b\n%Y')
df.loc[df.index.day != 1, 'str_date'] = ''
и может правильно установить первый день месяца, попробовав наоборот
df['str_date'] = ''
df.loc[df.index.day == 1, 'str_date'] = df.index.strftime('%b %Y')
дает ошибку: ValueError: не удалось транслировать входной массив из формы (350) в форму (11). Есть ли способ сделать это?






Вы можете проверить с .loc назначить с Series
df.loc[df.index.day==1,'str_date']=pd.Series(df.index.strftime('%b-%Y'),index=df.index)
df
str_date
obs_date
2018-01-01 Jan-2018
2018-01-02 NaN
2018-01-03 NaN
2018-01-04 NaN
2018-01-05 NaN
2018-01-06 NaN
2018-02-01 Feb-2018
Проблема в том, что левая и правая части вашего задания имеют разные размеры. Вместо этого вы можете использовать pd.Index.where для одновременного назначения и маскирования:
df['str_date'] = df.index.where(df.index.day == 1)
print(df)
# str_date
# obs_date
# 2018-01-01 2018-01-01
# 2018-01-02 NaT
# 2018-01-03 NaT
# 2018-01-04 NaT
# 2018-01-05 NaT
# 2018-01-06 NaT
# 2018-02-01 2018-02-01
Если вам нужно конкретное форматирование строки, вы можете вызвать strftime для результата:
df['str_date'] = df.index.where(df.index.day == 1).strftime('%b-%Y')
print(df)
# str_date
# obs_date
# 2018-01-01 Jan-2018
# 2018-01-02 NaT
# 2018-01-03 NaT
# 2018-01-04 NaT
# 2018-01-05 NaT
# 2018-01-06 NaT
# 2018-02-01 Feb-2018
Спасибо - это решило проблему, нужно также df['str_date'] = df['str_date'].str.replace('NaT', '', regex=False) для удаления 'NaT'
Вы получаете сообщение об ошибке, потому что
df.index.day == 1содержит только 11 значений, и вы пытаетесь установить эти 11 значений в значения len вашего фрейма данных.