Pandas: создайте временной ряд, заполненный последним днем ​​​​года

Скажем, у меня есть временной ряд Pandas с нерегулярными интервалами.

2010-01-04   88.82 
2010-11-29   90.70 
2010-12-01   90.09  
2011-02-26   90.10 
2011-08-01   90.55  
2011-09-21   89.50  
2012-04-01   89.06 
2012-04-30   90.22  
2012-05-03   90.21

Я хотел бы создать из индекса другую временную серию, в которой столбец заполняется последней датой года. Таким образом, для дат 2010 г. будет отображаться 2010-12-01, а для дат 2011 г. - 21-09-2011 и т. д. Желаемый результат:

2010-01-04   2010-12-01
2010-11-29   2010-12-01
2010-12-01   2010-12-01 
2011-02-26   2011-09-21
2011-08-01   2011-09-21 
2011-09-21   2011-09-21  
2012-04-01   2012-05-03
2012-04-30   2012-05-03 
2012-05-03   2012-05-03

Я могу извлечь индекс и сгруппировать их по годам.

end_dates=[]
df_idx = df.index
year_df = df_idx.groupby(df_idx.year)
for yr in year_df.keys():
    end_dates.append(max(year_df[yr]))

Это дает мне список годовых дат окончания. Но как связать эти конечные даты с исходным индексом, чтобы получить желаемый результат?


person Spinor8    schedule 04.06.2017    source источник


Ответы (1)


Убедитесь, что ваш индекс является объектом datetimeindex.

Если у вас есть серия панд, вы можете использовать это:

s.to_frame().assign(end_dates=s.groupby(s.index.year).transform(lambda x: x.index.max()))

или если у вас уже есть кадр данных:

df.assign(end_dates=df.groupby(df.index.year)['A'].transform(lambda x: x.index.max()))

Вывод:

                1  end_dates
0                           
2010-01-04  88.82 2010-12-01
2010-11-29  90.70 2010-12-01
2010-12-01  90.09 2010-12-01
2011-02-26  90.10 2011-09-21
2011-08-01  90.55 2011-09-21
2011-09-21  89.50 2011-09-21
2012-04-01  89.06 2012-05-03
2012-04-30  90.22 2012-05-03
2012-05-03  90.21 2012-05-03
person Scott Boston    schedule 04.06.2017
comment
Спасибо, Скотт. Я получаю эту ошибку от функции назначения. ValueError: неправильное количество переданных элементов 2, размещение подразумевает 1. Мой исходный фрейм данных на самом деле состоит из двух столбцов, поэтому мне пришлось изменить ваш код, чтобы извлечь столбец и превратить его обратно в фрейм данных перед назначением, т.е. df.assign(end_dates=df. iloc[:,0].to_frame().groupby(df.index.year).transform(lambda x: x.index.max())) - person Spinor8; 04.06.2017
comment
Есть ли ваша дата в индексе, если нет, вы можете установить_индекс, а затем запустить второй оператор. и после этого reset_index. - person Scott Boston; 04.06.2017
comment
Да, дата есть в указателе. Я не совсем понимаю, что вы имеете в виду, если дата не является индексом. Спасибо за терпеливость. - person Spinor8; 04.06.2017
comment
Что происходит, когда вы запускаете второй оператор как есть? - person Scott Boston; 04.06.2017
comment
Это дает следующую ошибку для assign. ValueError: неправильное количество переданных элементов 2, размещение подразумевает 1. - person Spinor8; 04.06.2017
comment
Если я запущу то, что указано в скобках, end_dates=df.groupby(df.index.year).transform(lambda x: x.index.max(), он покажет фрейм данных с двумя столбцами плюс индекс даты и времени. - person Spinor8; 04.06.2017
comment
Вот почему я извлек первый столбец с помощью df.iloc[:,0] и преобразовал обратно в фрейм данных. - person Spinor8; 04.06.2017
comment
Извини.. дома, просто уложи детей вздремнуть. Хорошо, что вам нужно сделать, это указать столбец после части groupby. Вы видите в моем отредактированном ответе, где у меня есть ['A'], просто выберите любой столбец, это не имеет значения. - person Scott Boston; 04.06.2017