Копирование значения на основе самого раннего дня месяца datetimeindex

#python #pandas #dataframe #datetime

#python #панды #фрейм данных #datetime

Вопрос:

У меня есть фрейм данных с datetimeindex и столбцом Val. Это значение меняется ежедневно.

Я хотел бы создать новый столбец, который будет значением, которое было в Val в самый ранний день месяца. Обратите внимание, я не сказал «первый» день месяца. Самым ранним днем в индексе может быть 2-й, 3-й, 10-й и т.д… Затем это значение должно распространяться до самого раннего дня следующего месяца.

В приведенном ниже примере для 2020-01-02 я бы хотел 1.764052, и чтобы это продолжалось до 2020-01-31. Затем для 2020-02-03 я бы хотел 0,864436, и это продолжалось до первой даты, которая появляется в марте.

Если мы не сможем зайти так далеко, будет достаточно даже логической маски, просто указывающей, является ли дата индекса самой ранней в месяце, и я могу как-то отсортировать столбец значений из этого. Заранее спасибо.

 import numpy as np
import pandas as pd

np.random.seed(0)
rng = pd.date_range('2020-01-02', periods=27, freq='B')
df = pd.DataFrame({ 'Val' : np.random.randn(len(rng)) }, index=rng)
df['Want'] = 99
df

                Val  Want
2020-01-02  1.764052    1.764052    
2020-01-03  0.400157    1.764052    
2020-01-06  0.978738    1.764052    
2020-01-07  2.240893    1.764052    
2020-01-08  1.867558    1.764052    
2020-01-09 -0.977278    1.764052    
2020-01-10  0.950088    1.764052    
2020-01-13 -0.151357    1.764052    
2020-01-14 -0.103219    1.764052    
2020-01-15  0.410599    1.764052    
2020-01-16  0.144044    1.764052    
2020-01-17  1.454274    1.764052    
2020-01-20  0.761038    1.764052    
2020-01-21  0.121675    1.764052    
2020-01-22  0.443863    1.764052    
2020-01-23  0.333674    1.764052    
2020-01-24  1.494079    1.764052    
2020-01-27 -0.205158    1.764052    
2020-01-28  0.313068    1.764052    
2020-01-29 -0.854096    1.764052    
2020-01-30 -2.552990    1.764052    
2020-01-31  0.653619    1.764052    
2020-02-03  0.864436    0.864436    
2020-02-04 -0.742165    0.864436    
2020-02-05  2.269755    0.864436    
2020-02-06 -1.454366    0.864436    
2020-02-07  0.045759    0.864436

Ответ №1:

  • groupby() год и месяц в индексе
  • transform() для возврата для всех строк
  • lambda функция для выбора первого значения в сгруппированном ряду
  • можно упростить до «первого»
 import numpy as np
np.random.seed(0)
rng = pd.date_range('2020-01-02', periods=27, freq='B')
df = pd.DataFrame({ 'Val' : np.random.randn(len(rng)) }, index=rng)
df['Want'] = 99
df["Want"] = df.groupby([df.index.year,df.index.month])["Val"].transform(lambda s: s[0])
df
 
Значение Хотите
2020-01-02 00:00:00 1.76405 1.76405
2020-01-03 00:00:00 0.400157 1.76405
2020-01-06 00:00:00 0.978738 1.76405
2020-01-07 00:00:00 2.24089 1.76405
2020-01-08 00:00:00 1.86756 1.76405
2020-01-09 00:00:00 -0.977278 1.76405
2020-01-10 00:00:00 0.950088 1.76405
2020-01-13 00:00:00 -0.151357 1.76405
2020-01-14 00:00:00 -0.103219 1.76405
2020-01-15 00:00:00 0.410599 1.76405
2020-01-16 00:00:00 0.144044 1.76405
2020-01-17 00:00:00 1.45427 1.76405
2020-01-20 00:00:00 0.761038 1.76405
2020-01-21 00:00:00 0.121675 1.76405
2020-01-22 00:00:00 0.443863 1.76405
2020-01-23 00:00:00 0.333674 1.76405
2020-01-24 00:00:00 1.49408 1.76405
2020-01-27 00:00:00 -0.205158 1.76405
2020-01-28 00:00:00 0.313068 1.76405
2020-01-29 00:00:00 -0.854096 1.76405
2020-01-30 00:00:00 -2.55299 1.76405
2020-01-31 00:00:00 0.653619 1.76405
2020-02-03 00:00:00 0.864436 0.864436
2020-02-04 00:00:00 -0.742165 0.864436
2020-02-05 00:00:00 2.26975 0.864436
2020-02-06 00:00:00 -1.45437 0.864436
2020-02-07 00:00:00 0.0457585 0.864436