通过Python中的大熊猫将每日库存数据转换为每周库存数据

Jud*_*ing 9 python yahoo-finance pandas

我有一个DataFrame存储每日数据,如下所示:

Date              Open        High         Low       Close   Volume
2010-01-04   38.660000   39.299999   38.509998   39.279999  1293400   
2010-01-05   39.389999   39.520000   39.029999   39.430000  1261400   
2010-01-06   39.549999   40.700001   39.020000   40.250000  1879800   
2010-01-07   40.090000   40.349998   39.910000   40.090000   836400   
2010-01-08   40.139999   40.310001   39.720001   40.290001   654600   
2010-01-11   40.209999   40.520000   40.040001   40.290001   963600   
2010-01-12   40.160000   40.340000   39.279999   39.980000  1012800   
2010-01-13   39.930000   40.669998   39.709999   40.560001  1773400   
2010-01-14   40.490002   40.970001   40.189999   40.520000  1240600   
2010-01-15   40.570000   40.939999   40.099998   40.450001  1244200   
Run Code Online (Sandbox Code Playgroud)

我打算做的是将它合并到基于每周的数据中.分组后:

  1. 该日期应为每星期一(在这一点上,节日的场景应该星期一,不是交易日认为,我们应该运用第一个交易日在本周的日期).
  2. 开盘应该是周一(或当周的第一个交易日)开盘.
  3. 收盘价应该是周五(或当周的最后一个交易日)收盘价.
  4. 高位应该是本周交易日的最高点.
  5. 低应该是本周交易日的最低点.
  6. Volumn应该是本周所有交易日数量的总和.

它应该是这样的:

Date              Open        High         Low       Close   Volume
2010-01-04   38.660000   40.700001   38.509998   40.290001  5925600   
2010-01-11   40.209999   40.970001   39.279999   40.450001  6234600   
Run Code Online (Sandbox Code Playgroud)

目前,我的代码片段如下所示,我应该使用哪个函数将基于日常的数据映射到预期的每周数据?非常感谢!

import pandas_datareader.data as web

start = datetime.datetime(2010, 1, 1)
end = datetime.datetime(2016, 12, 31)
f = web.DataReader("MNST", "yahoo", start, end, session=session)
print f
Run Code Online (Sandbox Code Playgroud)

Ste*_*fan 12

您可以resample(按周),offset(班次)和apply聚合规则如下:

logic = {'Open'  : 'first',
         'High'  : 'max',
         'Low'   : 'min',
         'Close' : 'last',
         'Volume': 'sum'}

offset = pd.offsets.timedelta(days=-6)

f = pd.read_clipboard(parse_dates=['Date'], index_col=['Date'])
f.resample('W', loffset=offset).apply(logic)
Run Code Online (Sandbox Code Playgroud)

要得到:

                 Open       High        Low      Close   Volume
Date                                                           
2010-01-04  38.660000  40.700001  38.509998  40.290001  5925600
2010-01-11  40.209999  40.970001  39.279999  40.450001  6234600
Run Code Online (Sandbox Code Playgroud)


goo*_*ofd 11

通常,假设您拥有指定格式的数据框,则需要执行以下步骤:

  1. 放入Date索引
  2. resample 指数.

您所拥有的是将不同功能应用于不同列的情况.见.

您可以通过各种方式重新取样.例如,您可以采用值的平均值或计数等.检查熊猫重新取样.

您还可以应用自定义聚合器(请检查相同的链接).考虑到这一点,您的案例的代码段可以给出:

f['Date'] = pd.to_datetime(f['Date'])
f.set_index('Date', inplace=True)
f.sort_index(inplace=True)

def take_first(array_like):
    return array_like[0]

def take_last(array_like):
    return array_like[-1]

output = f.resample('W',                                 # Weekly resample
                    how={'Open': take_first, 
                         'High': 'max',
                         'Low': 'min',
                         'Close': take_last,
                         'Volume': 'sum'}, 
                    loffset=pd.offsets.timedelta(days=-6))  # to put the labels to Monday

output = output[['Open', 'High', 'Low', 'Close', 'Volume']]
Run Code Online (Sandbox Code Playgroud)

这里W表示每周重新采样,默认情况下从周一到周日.使用标签为星期一loffset.有几个预定义的日期说明符.看看熊猫补偿.您甚至可以定义自定义偏移(请参阅参考资料).

回到重采样方法.在这里Open,Close您可以指定自定义方法来获取第一个值等,并将函数句柄传递给how参数.

这个答案是基于数据似乎是每天的假设,即每天只有1个条目.此外,非营业日没有数据.即周六和太阳.因此,将本周的最后一个数据点作为周五的数据点是可以的.如果您愿意,可以使用工作周代替"W".此外,对于更复杂的数据,您可能希望使用它groupby来对每周数据进行分组,然后处理其中的时间索引.

btw解决方案的要点可以在以下网址找到:https: //gist.github.com/prithwi/339f87bf9c3c37bb3188

  • 最近的 Pandas 现在使用“apply()”而不是 how 参数。您仍然可以提供这样的字典来申请。您也可以只使用字符串 'first' 而不是您的函数 first,以及 'last' 代替您的函数 `take_last`。 (2认同)
  • 像这样基于wordsforthewise的评论: f.resample('W',loffset=pd.offsets.timedelta(days=-6)).apply({'Open': 'first', 'High': 'max', '最低价': '分钟','收盘价': '最后', '交易量': '总和'}) (2认同)

小智 6

我有完全相同的问题,并在这里找到了一个很好的解决方案。

https://www.techtrekking.com/how-to-convert-daily-time-series-data-into-weekly-and-monthly-using-pandas-and-python/

每周代码发布在下面。

import pandas as pd
import numpy as np

print('*** Program Started ***')

df = pd.read_csv('15-06-2016-TO-14-06-2018HDFCBANKALLN.csv')

# ensuring only equity series is considered
df = df.loc[df['Series'] == 'EQ']

# Converting date to pandas datetime format
df['Date'] = pd.to_datetime(df['Date'])
# Getting week number
df['Week_Number'] = df['Date'].dt.week
# Getting year. Weeknum is common across years to we need to create unique index by using year and weeknum
df['Year'] = df['Date'].dt.year

# Grouping based on required values
df2 = df.groupby(['Year','Week_Number']).agg({'Open Price':'first', 'High Price':'max', 'Low Price':'min', 'Close Price':'last','Total Traded Quantity':'sum'})
# df3 = df.groupby(['Year','Week_Number']).agg({'Open Price':'first', 'High Price':'max', 'Low Price':'min', 'Close Price':'last','Total Traded Quantity':'sum','Average Price':'avg'})
df2.to_csv('Weekly_OHLC.csv')
print('*** Program ended ***')
Run Code Online (Sandbox Code Playgroud)