在日期时间索引上减去不同粒度的数据帧列

2024-10-03 23:29:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些价格数据(比如来自yahoo finance)以每日粒度datetime变量作为索引,让我们称之为df,并将微软收盘价作为值变量。要获得月平均收盘价,我显然可以做以下两种操作之一:

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()

对我来说,它们看起来非常相似,唯一不同的是,在重新采样时,新的日期时间索引是月底,groupby To_期间的索引是yyyy-mm

现在,我想在df中添加一个列,其粒度为每日收盘价与月平均值的偏差。因此,2020年1月1日-平均值(2020年1月20日),2020年1月2日-平均值(2020年1月20日),2020年2月1日-平均值(2020年2月20日)

因为dfm和df有不同的索引,我不能只做df-dfm

我唯一能想到的就是通过df循环,在dfm上放置一个计数器,并在循环中放置一个if语句,这是一种非常c类型的方法,但不是非常pythonic的。我猜它看起来会像这样(但这不起作用):

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]

Tags: importdfcloseindexifascounter粒度
1条回答
网友
1楼 · 发布于 2024-10-03 23:29:14

您可以将DatetimeIndex转换为月周期,因此可以减去dfm2,只有这样才有必要转换为numpy数组,因为减去的Series的索引与原始df的索引不同,以防止满NaN列:

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

另一个更简单的解决方案是使用^{}与原始索引相同:

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]

相关问题 更多 >