вычитание столбцов фрейма данных с разной степенью детализации по индексу datetime - PullRequest
1 голос
/ 29 мая 2020

У меня есть некоторые данные о ценах (например, от Yahoo Finance) с переменной datetime с ежедневной детализацией в качестве индекса, можно вызвать этот df и сказать, что это цена закрытия Microsoft в качестве переменной значения. Чтобы получить среднемесячную цену закрытия, я, очевидно, могу сделать одно из этих двух:

import yfinance as yf
import pandas as pd
df = yf.download("CMG", start="2012-01-01",end="2020-01-01" )
dfm = df.resample("M").mean()
dfm2 = df.groupby(df.index.to_period("M")).mean()

На мой взгляд, они выглядят очень похожими, с той лишь разницей, что я могу сказать, что при повторной выборке новый индекс даты и времени является концом month и groupby to_period будут иметь индекс гггг-мм.

Теперь я хочу добавить столбец к df с ежедневной детализацией, который имеет для каждой дневной цены закрытия отклонение от ее среднемесячного значения. Итак, 1 / янв / 2020 - среднее (янв-20), 2 / янв / 2020 - среднее (янв-20), 1 / фев / 2020 - среднее (фев-20).

Поскольку dfm и df имеют разные индексы, я не могу просто выполнить df-dfm.

Единственное, что я могу придумать, это l oop через df, поставить счетчик на dfm и поставить оператор if в l oop, очень похож на подход типа c, но не на pythoni c. Думаю, это выглядело бы так (но это не сработало):

counter = 0
df["dailyminusmonthly"] =""

for i in df:
if i.index <= dfm[counter].index:
    i.dailyminusmonthly = i.close - dfm.close[counter]
else:
    counter = counter +1
    i.dailyminusmonthly = i.close - dfm.close[counter]

1 Ответ

1 голос
/ 29 мая 2020

Вы можете преобразовать DatetimeIndex в месячный период, поэтому вы можете вычесть dfm2, только тогда необходимо преобразовать в массив numpy, потому что индекс вычитаемого Series отличается от исходного df для предотвращения полного * Столбец 1005 * s:

df['dailyminusmonthly1']= (df['Close'].to_period('M')
                                    .sub(df.groupby(df.index.to_period("M"))['Close'].mean())
                                    .to_numpy())

Другое более простое решение - использовать Resampler.transform с тем же индексом, что и оригинал:

df['dailyminusmonthly2']= df['Close'].sub(df.resample("M")['Close'].transform('mean'))

print (df)
                  Open        High         Low       Close   Adj Close  \
Date                                                                     
2012-01-03  343.700012  350.489990  340.000000  341.269989  341.269989   
2012-01-04  346.000000  349.980011  345.010010  348.750000  348.750000   
2012-01-05  346.880005  351.980011  342.570007  350.480011  350.480011   
2012-01-06  348.880005  352.630005  347.350006  348.950012  348.950012   
2012-01-09  349.000000  349.489990  336.290009  339.739990  339.739990   
               ...         ...         ...         ...         ...   
2019-12-24  827.099976  829.409973  823.159973  828.890015  828.890015   
2019-12-26  829.409973  839.280029  828.239990  838.599976  838.599976   
2019-12-27  839.969971  840.000000  835.000000  836.789978  836.789978   
2019-12-30  838.169983  838.750000  829.010010  836.070007  836.070007   
2019-12-31  837.239990  842.270020  833.359985  837.109985  837.109985   

            Volume  dailyminusmonthly1  dailyminusmonthly2  
Date                                                        
2012-01-03  728100          -13.559013          -13.559013  
2012-01-04  743100           -6.079002           -6.079002  
2012-01-05  672300           -4.348991           -4.348991  
2012-01-06  370700           -5.878990           -5.878990  
2012-01-09  748600          -15.089012          -15.089012  
           ...                 ...                 ...  
2019-12-24   91900            3.640494            3.640494  
2019-12-26  255400           13.350455           13.350455  
2019-12-27  201900           11.540458           11.540458  
2019-12-30  211400           10.820487           10.820487  
2019-12-31  282200           11.860465           11.860465  

[2012 rows x 8 columns]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...