Добавьте значение к текущей строке фрейма данных с индексом ‘datetime’, если дата находится между текущим и предыдущим индексами

#python #python-3.x #pandas

#python #python-3.x #pandas

Вопрос:

У меня есть tow dataframes stockData и EPSdata , как показано ниже.
stockData будет

             Close 
Date
2018-12-31  157.066376
2018-09-30  223.994431
2018-06-30  183.036682
2018-03-31  165.263504
2017-12-31  166.014908
2017-09-30  150.650375
2017-06-30  140.227097
2017-03-31  139.301605
2016-12-31  111.821404
2016-09-30  108.589523
2016-06-30  91.333252
2016-03-31  103.495514
2015-12-31  99.414101
2015-09-30  103.730179
......
  

и EPSData будет

            Surprise_perc
Date
2018-11-01          4.30
2018-07-31          7.83
2018-05-01          1.49
2018-02-01          1.83
2017-11-02         10.70
2017-08-01          6.37
2017-05-02          3.96
2017-01-31          4.35
2016-10-25          0.60
2016-07-26          2.16
.......
  

как я могу объединить оба этих фрейма данных?
Первая точка данных в EPSData 2018-11-01 4.30 » должна быть добавлена к Q4 в stockData ie, к точке данных « 2018-12-31 157.066376 «.
Результат должен выглядеть следующим образом

             Close       Surprise_perc
Date
2018-12-31  157.066376  4.30
2018-09-30  223.994431  7.83
2018-06-30  183.036682  1.49
2018-03-31  165.263504  1.83
2017-12-31  166.014908  10.70
2017-09-30  150.650375  6.37
2017-06-30  140.227097  3.96
2017-03-31  139.301605  4.35
2016-12-31  111.821404  0.60
2016-09-30  108.589523  2.16
.....
  

здесь оба фрейма данных индексируются по датам.

Ответ №1:

Используйте merge_asof с DataFrame.sort_index :

 df = (pd.merge_asof(stockData.sort_index(), 
                    EPSData.sort_index(), 
                    left_index=True, 
                    right_index=True)
        .sort_index(ascending=False))
print (df)
                 Close  Surprise_perc
Date                                 
2018-12-31  157.066376           4.30
2018-09-30  223.994431           7.83
2018-06-30  183.036682           1.49
2018-03-31  165.263504           1.83
2017-12-31  166.014908          10.70
2017-09-30  150.650375           6.37
2017-06-30  140.227097           3.96
2017-03-31  139.301605           4.35
2016-12-31  111.821404           0.60
2016-09-30  108.589523           2.16
2016-06-30   91.333252            NaN
2016-03-31  103.495514            NaN
2015-12-31   99.414101            NaN
2015-09-30  103.730179            NaN
  

Комментарии:

1. @Shijith — Возможно ли создать новый вопрос с этой новой проблемой?

2. @Shijith — Но одна идея заключается в том, чтобы использовать небольшой взлом — EPSData = EPSData.fillna('tmp') , применить решение и последнее df = df.repalce('tmp', np.nan)

3. Большое вам спасибо за быстрый ответ и представление меня merge_asof. У меня это хорошо работает для большинства акций. Но у меня есть несколько акций, для которых данные ‘EPSData’ отсутствуют в течение некоторых кварталов. итак, я внес небольшое изменение и добавил новый параметр для допустимости (60 дней), tolerance=pd.Timedelta('60d') . отредактированный код выглядит так: df = pd.merge_asof(a.sort_index(), EPS.sort_index(), left_index=True, right_index=True,tolerance=pd.Timedelta('60d')).sort_index(ascending=False) . Еще раз спасибо за помощь.

4. @ jezrael, также нет значений ‘NaN’, данные похожи на Q1, а затем на Q4, между ними нет столбцов. Может быть, мне нужно найти лучший источник данных. Спасибо.

5. tolerance=pd.Timedelta('90d') хорошо работает для всех акций, проблема с 60 заключается в том, что некоторые компании будут сообщать о прибылях и убытках в течение месяца.