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

Posted

技术标签:

【中文标题】通过 Python 中的 pandas 将每日库存数据转换为每周【英文标题】:converting daily stock data to weekly-based via pandas in Python 【发布时间】:2016-04-08 11:10:30 【问题描述】:

我有一个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   

我打算将其合并到基于每周的数据中。分组后:

    日期应为每周一(此时应考虑周一非交易日的节假日情况,应以当周第一个交易日为日期)。 开盘应该是周一(或本周的第一个交易日)开盘。 收盘价应为周五(或本周最后一个交易日)收盘价。 High应该是本周交易日的最高High。 最低价应该是本周交易日的最低价。 成交量应该是当周所有交易日成交量的总和。

应该是这样的:

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   

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

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

【问题讨论】:

您是否已经采取措施实现您想要的结果?如果是这样,您的尝试在哪里失败了? 我对 pandas 完全陌生,所以我不知道应该从哪个方向开始。如果您可以提供一些正确的功能,那就太好了。看来我们需要一个group 函数,它可以分别对每一列应用关于如何合并每一列的规则。 @Stefan 【参考方案1】:

在@Stefan 的答案中添加最近的pandas API 为loffset 自版本 1.1.0 起已弃用,后来被删除。

df = pd.read_clipboard(parse_dates=['Date'], index_col=['Date'])
logic = 'Open'  : 'first',
         'High'  : 'max',
         'Low'   : 'min',
         'Close' : 'last',
         'Volume': 'sum'

dfw = df.resample('W').apply(logic)
# set the index to the beginning of the week
dfw.index = dfw.index - pd.tseries.frequencies.to_offset("6D")

【讨论】:

【参考方案2】:

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

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 ***')

【讨论】:

【参考方案3】:

不是直接的答案,但假设列是日期(表的转置),没有丢失日期。

'''sum up daily results in df to weekly results in wdf'''
wdf = pd.DataFrame(index = df.index)
for i in range(len(df.columns)):
    if (i!=0) & (i%7==0):
        wdf['week'+str(i//7)]= df[df.columns[i-7:i]].sum(axis = 1)

【讨论】:

【参考方案4】:

您可以将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)

得到:

                 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

【讨论】:

重读你的大纲。对于星期一,您希望从以下日期开始关闭,而不是上一个星期五? 不,我的意思是收盘应该是本周最后一个交易日的收盘,不是上一个:] 上面的例子有 1 月 8 日星期五的收盘价,星期一,1 月 11 日,星期五,1 月 15 日,星期一,1 月 18 日。您想要这些星期一的哪些日期? 1 月 15 日星期五关闭到 1 月 11 日星期一? 此解决方案的计算成本更高。您正在重采样多次,其核心是 groupby 操作,即基本上是单次重采样所需时间的 5 倍。 没错。它首先回答了允许重新采样的功能问题,并列出了各种选项。对于 5 年的每日数据:-%timeit f.Open.resample('W-MON', how='last'):100 loops, best of 3: 11.1 ms per loop【参考方案5】:

一般来说,假设你有你指定的形式的数据框,你需要做以下步骤:

    Date 放入索引中 resample 索引。

您所拥有的是一个将不同功能应用于不同列的案例。 See.

您可以通过多种方式重新采样。例如您可以取值或计数的平均值等。检查pandas resample。

您还可以应用自定义聚合器(查看相同的链接)。 考虑到这一点,您案例的代码 sn-p 可以如下给出:

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']]

这里,W 表示每周重新采样,默认情况下跨越周一到周日。要将标签保留为星期一,请使用 loffset。 有几个预定义的日期说明符。看看pandas offsets。您甚至可以定义自定义偏移量 (see)。

回到重采样方法。对于OpenClose,您可以指定自定义方法来获取第一个值等,并将函数句柄传递给how 参数。

此答案基于数据似乎是每天的假设,即每天您只有 1 个条目。此外,非工作日也没有数据。即周六和周日。因此,将本周的最后一个数据点作为周五的数据点是可以的。如果您愿意,您可以使用商务周而不是“W”。此外,对于更复杂的数据,您可能需要使用groupby 对每周数据进行分组,然后处理其中的时间索引。

顺便说一句,解决方案的要点可以在以下位置找到: https://gist.github.com/prithwi/339f87bf9c3c37bb3188

【讨论】:

最新的 pandas 现在使用 'apply()' 而不是 how 参数。您仍然可以提供这样的字典来应用。你也可以只使用字符串'first'而不是你的函数first,和'last'而不是你的函数take_last 这样基于 wordsforthewise 的评论:f.resample('W',loffset=pd.offsets.timedelta(days=-6)).apply('Open': 'first', '高':'max','低':'min','Close':'last','Volume':'sum')

以上是关于通过 Python 中的 pandas 将每日库存数据转换为每周的主要内容,如果未能解决你的问题,请参考以下文章

使用 pandas python 计算每日气候学

如何从 pandas 数据框中的大型每日 JSON 数据集计算平均月值?

python pandas 按一天中的小时求和

需求:将excel表中的数据通过PYTHON脚本编写,每日自动导入到oracle数据库相应的一张表格中。

将 JSON 时间戳字符串转换为 pandas 数据框中的 python 日期

Python Pandas:将参数传递给 agg() 中的函数