使用Pandas将每日数据重新采样为每月(日期格式)

时间:2017-02-12 18:45:23

标签: python pandas

我正在尝试在Pandas DataFrame中从每日到每月重新采样一些数据。我是大熊猫的新手,也许我需要首先格式化日期和时间,然后才能做到这一点,但我没有找到一个好的教程,以正确的方式使用导入的时间序列数据。我发现的一切都是自动从Yahoo或Quandl导入数据。

以下是我在DataFrame中的内容: dataframe segment screenshot

以下是我用来创建DataFrame的代码:

#Import excel file into a Pandas DataFrame
df = pd.read_excel(open('2016_forex_daily_returns.xlsx','rb'), sheetname='Sheet 1')

#Calculate the daily returns
df['daily_ret'] = df['Equity'].pct_change()

# Assume an average annual risk-free rate over the period of 5%
df['excess_daily_ret'] = df['daily_ret'] - 0.05/252

有人可以帮我了解我需要对DataFrame中的“日期”和“时间”列进行操作,以便重新取样吗?

4 个答案:

答案 0 :(得分:7)

对于创建DataFrame,可以使用:

df = pd.read_excel('2016_forex_daily_returns.xlsx', sheetname='Sheet 1')
print (df)
        Date      Time  Equity
0 2016-01-03  22:16:22  300.38
1 2016-01-04  22:16:00  300.65
2 2016-01-05  14:26:02  301.65
3 2016-01-06  19:08:13  302.10
4 2016-01-07  18:39:00  302.55
5 2016-01-08  22:16:04  308.24
6 2016-01-11  02:49:39  306.69
7 2016-01-14  15:46:39  307.93
8 2016-01-19  15:56:31  308.18

我认为您可以首先投放to_datetimedate,然后将resamplesummean等一些汇总函数一起使用:

df.Date = pd.to_datetime(df.Date)
df1 = df.resample('M', on='Date').sum()
print (df1)
             Equity  excess_daily_ret
Date                                 
2016-01-31  2738.37          0.024252

df2 = df.resample('M', on='Date').mean()
print (df2)
                Equity  excess_daily_ret
Date                                    
2016-01-31  304.263333          0.003032

df3 = df.set_index('Date').resample('M').mean()
print (df3)
                Equity  excess_daily_ret
Date                                    
2016-01-31  304.263333          0.003032

答案 1 :(得分:1)

首先,将“日期”和“时间”列之间用空格隔开。然后使用pd.to_datetime()将其转换为DateTime格式。

df = pd.read_excel('2016_forex_daily_returns.xlsx', sheetname='Sheet 1')
print(df)
        Date      Time  Equity
0 2016-01-03  22:16:22  300.38
1 2016-01-04  22:16:00  300.65
2 2016-01-05  14:26:02  301.65
3 2016-01-06  19:08:13  302.10
4 2016-01-07  18:39:00  302.55
5 2016-01-08  22:16:04  308.24
6 2016-01-11  02:49:39  306.69
7 2016-01-14  15:46:39  307.93
8 2016-01-19  15:56:31  308.18

df = df.drop(['Date', 'Time'], axis= 'columns').set_index(pd.to_datetime(df.Date + ' ' + df.Time))
df.index.name = 'Date/Time'
print(df)
                     Equity
Date/Time                  
2016-01-03 22:16:22  300.38
2016-01-04 22:16:00  300.65
2016-01-05 14:26:02  301.65
2016-01-06 19:08:13  302.10
2016-01-07 18:39:00  302.55
2016-01-08 22:16:04  308.24
2016-01-11 02:49:39  306.69
2016-01-14 15:46:39  307.93
2016-01-19 15:56:31  308.18

现在,您可以重新采样为所需的任何格式。

答案 2 :(得分:0)

要从每日数据重新采样到每月数据,可以使用resample方法。以下示例专门针对每日收益,展示了一种可能的解决方案。

以下数据取自AQR执行的分析。它代表2019年5月的市场每日收益。以下代码可用于将数据构造为pd.DataFrame

import pandas as pd

dates = pd.DatetimeIndex(['2019-05-01', '2019-05-02', '2019-05-03', '2019-05-06',
                         '2019-05-07', '2019-05-08', '2019-05-09', '2019-05-10',
                         '2019-05-13', '2019-05-14', '2019-05-15', '2019-05-16',
                         '2019-05-17', '2019-05-20', '2019-05-21', '2019-05-22',
                         '2019-05-23', '2019-05-24', '2019-05-27', '2019-05-28',
                         '2019-05-29', '2019-05-30', '2019-05-31'],
                         dtype='datetime64[ns]', name='DATE', freq=None)

daily_returns = array([-7.73787813e-03, -1.73277604e-03,  1.09124031e-02, -3.80437796e-03,
                       -1.66513456e-02, -1.67262934e-03, -2.77427734e-03,  4.01713274e-03,
                       -2.50407102e-02,  9.23270367e-03,  5.41897568e-03,  8.65419524e-03,
                       -6.83456209e-03, -6.54787106e-03,  9.04322511e-03, -4.05811322e-03,
                       -1.33152640e-02,  2.73398876e-03, -9.52000000e-05, -7.91438809e-03,
                       -7.16881982e-03,  1.19255102e-03, -1.24209547e-02])

daily_returns = pd.DataFrame(index = index, data= may.values, columns = ["returns"])

假设您没有每日价格数据,则可以使用以下代码从每日收益重新采样为每月收益。

>>> daily_returns.resample("M").apply(lambda x: ((x + 1).cumprod() - 1).last("D"))
-0.06532

如果您参考他们的monthly dataset,这确认了2019年5月的市场收益近似为-6.52%-0.06532

答案 3 :(得分:0)

我在这里创建了一个类似于您的随机DataFrame:

import numpy as np
import pandas as pd
dates = [x for x in pd.date_range(end=pd.datetime.today(), periods=1800)]
counts = [x for x in np.random.randint(0, 10000, size=1800)]
df = pd.DataFrame({'dates': dates, 'counts': counts}).set_index('dates')

以下是汇总每周总计数的过程,例如:

df['week'] = df.index.week
df['year'] = df.index.year
target_df = df.groupby(['year', 'week']).agg({'counts': np.sum})

target_df的输出为:

                counts
year    week    
2015    3       29877
        4       36859
        5       36872
        6       36899
        7       37769
 .      .         .
 .      .         .
 .      .         .