【问题标题】:Filter on the closest available date to month-end in a Pandas dataframe在 Pandas 数据框中过滤最接近月底的可用日期
【发布时间】:2016-12-10 13:55:28
【问题描述】:

我正在尝试使用 python 和 pandas 从 Yahoo Finance 下载证券价格数据,目的是在时间序列中以月末调整价格结束。

我的代码如下所示。我使用 ix 过滤数据框以生成业务月末日期列表。这适用于时间序列中除 2 个日期之外的所有日期,其中 2010 年 5 月 31 日和 2013 年 3 月 29 日均显示为空白,我认为这是因为这些是美国的联邦假日。

与其尝试为交易日创建日历,是否可以创建自定义频率或日历来简单地查找月末日期,如果不可用,则检查以前的日期直到找到一个值?例如,2013 年 3 月 31 日没有数据,因此检查 3 月 30 日(无数据)、3 月 29 日(无数据)、3 月 28 日(数据)-> 依次显示 3 月 28 日。

import io
import requests
from datetime import datetime
import pandas

ticker = 'SPY'
start_date = '2009-12-31'
end_date = '2016-12-08'
s_dt = datetime.strptime(start_date, '%Y-%m-%d')
e_dt = datetime.strptime(end_date, '%Y-%m-%d')

url = 'http://chart.finance.yahoo.com/table.csv?s={0}&a={1}&b={2}&c={3}&d={4}&e={5}&f={6}&g=d&ignore=.csv'
url = url.format(ticker, s_dt.month-1, s_dt.day, s_dt.year, e_dt.month-1, e_dt.day, e_dt.year)
data = requests.get(url).content

df = pandas.read_csv(io.StringIO(data.decode('utf-8')))
df.drop('Open', 1, inplace=True)
df.drop('High', 1, inplace=True)
df.drop('Low', 1, inplace=True)
df.drop('Volume', 1, inplace=True)
df.drop('Close', 1, inplace=True)
df.columns = ['date', ticker]

df['date'] = pandas.to_datetime(df['date'], format='%Y-%m-%d')    
df = df.set_index('date')
df = df.ix[pandas.date_range(start=start_date, end=end_date, freq='BM')]

【问题讨论】:

  • 你不能用pandas_datareader吗?见前。这个问题:stackoverflow.com/questions/22991567/…
  • 谢谢 - 我以前从未听说过 pandas_datareader。会调查的。
  • 如果你还没有它,你需要pip install它。然后您只需执行from pandas_datareader.data import DataReader ,您的完整数据框架将是df = DataReader('SPY', 'yahoo', '2009-12-31', '2016-12-08')

标签: python date datetime pandas


【解决方案1】:

我想出了一种使用 fillna 方法实现我想要的方法。

我原来的代码最后一行应该换成:

# expand series to add all dates in date range
df = df.ix[pandas.date_range(start=start_date, end=end_date, freq='d')]
# fill in the NaN values with the last available value
df = df.fillna(method='pad')
# reduce series to just business month-end dates
df = df.ix[pandas.date_range(start=start_date, end=end_date, freq='BM')]

【讨论】:

  • 除非你真的需要,否则不要使用.ix。请改用.loc.loc
【解决方案2】:

您可以使用pandas_datareaderpip install,如果您还没有的话)获取所有原始的每日数据

那你就做吧

from pandas_datareader.data import DataReader
df = DataReader('SPY', 'yahoo', '2009-12-31', '2016-12-08') 

你可以跳过后处理步骤,直接获取月度数据,但是这个界面有点挑剔,你可以这样做:

from pandas_datareader.yahoo.daily import YahooDailyReader 
df_monthly = YahooDailyReader('SPY', '2009-12-31', '2016-12-08', interval='m').read()

【讨论】:

    猜你喜欢
    • 2017-07-27
    • 2016-09-02
    • 2023-02-06
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-29
    • 2017-10-06
    相关资源
    最近更新 更多