从 df 获取一个月的第一天和最后一天

Get the first and the last day of a month from the df

这是我的数据框的样子:

datetime      open      high     low       close    
2006-01-02    4566.95   4601.35  4542.00   4556.25
2006-01-03    4531.45   4605.45  4531.45   4600.25  
2006-01-04    4619.55   4707.60  4616.05   4694.14
.
.
.

需要在 %

中计算每月 Returns
Formula: (Month Closing Price - Month Open Price) / Month Open Price

我似乎无法获得一个月的开盘价和收盘价,因为在我的 df 中,大多数月份都没有该月 1 日的日志。所以计算起来有点麻烦。

非常感谢任何帮助!

您需要使用 groupbyagg 函数来获取每个月每列的第一个和最后一个值:

import pandas as pd
df = pd.read_csv("dt.txt")
df["datetime"] = pd.to_datetime(df["datetime"])
df.set_index("datetime", inplace=True)
resultDf = df.groupby([df.index.year, df.index.month]).agg(["first", "last"])
resultDf["new_column"] = (resultDf[("close", "last")] - resultDf[("open", "first")])/resultDf[("open", "first")]
resultDf.index.rename(["year", "month"], inplace=True)
resultDf.reset_index(inplace=True)
resultDf

上面的代码将生成一个包含多索引列的数据框。所以,例如,如果你想获得 2010 年的行,你可以这样做:

resultDf[resultDf["year"] == 2010]

您可以创建自定义石斑鱼,如下所示:

import pandas as pd
import numpy as np
from io import StringIO

csvfile = StringIO(
"""datetime\topen\thigh\tlow\tclose
2006-01-02\t4566.95\t4601.35\t4542.00\t4556.25
2006-01-03\t4531.45\t4605.45\t4531.45\t4600.25  
2006-01-04\t4619.55\t4707.60\t4616.05\t4694.14""")

df = pd.read_csv(csvfile, sep = '\t', engine='python')

df.datetime = pd.to_datetime(df.datetime, format = "%Y-%m-%d")

dg = df.groupby(pd.Grouper(key='datetime', axis=0, freq='M'))

然后每组 dg 按月分开,由于我们将 datetime 转换为 pandas.datetime 我们可以对其使用经典算法:

def monthly_return(datetime, close_value, open_value):
    index_start = np.argmin(datetime)
    index_end = np.argmax(datetime)
    return (close_value[index_end] - open_value[index_start]) / open_value[index_start]

dg.apply(lambda x : monthly_return(x.datetime, x.close, x.open))
Out[97]: 
datetime
2006-01-31    0.02785
Freq: M, dtype: float64

当然可以使用纯函数方法而不是使用 monthly_return 函数