使用python和pandas将OHLC库存数据转换为不同的时间范围

kgr*_*kgr 15 python stock pandas

有人可以指出我在与熊猫的 OHLC数据时间框架转换方面的正确方向吗?我正在尝试做的是使用较低时间帧的数据构建具有较高时间帧数据的Dataframe.

例如,给定我有以下一分钟(M1)数据:

                       Open    High     Low   Close  Volume
Date                                                       
1999-01-04 10:22:00  1.1801  1.1819  1.1801  1.1817       4
1999-01-04 10:23:00  1.1817  1.1818  1.1804  1.1814      18
1999-01-04 10:24:00  1.1817  1.1817  1.1802  1.1806      12
1999-01-04 10:25:00  1.1807  1.1815  1.1795  1.1808      26
1999-01-04 10:26:00  1.1803  1.1806  1.1790  1.1806       4
1999-01-04 10:27:00  1.1801  1.1801  1.1779  1.1786      23
1999-01-04 10:28:00  1.1795  1.1801  1.1776  1.1788      28
1999-01-04 10:29:00  1.1793  1.1795  1.1782  1.1789      10
1999-01-04 10:31:00  1.1780  1.1792  1.1776  1.1792      12
1999-01-04 10:32:00  1.1788  1.1792  1.1788  1.1791       4
Run Code Online (Sandbox Code Playgroud)

它有开放,高,低,关闭(OHLC)和每分钟的音量值我想建立一组5分钟的读数(M5),看起来像这样:

                       Open    High     Low   Close  Volume
Date                                                       
1999-01-04 10:25:00  1.1807  1.1815  1.1776  1.1789      91
1999-01-04 10:30:00  1.1780  1.1792  1.1776  1.1791      16
Run Code Online (Sandbox Code Playgroud)

所以工作流程是这样的:

  • Open是时间窗口中第一行的Open
  • 高是时间窗口中的最高点
  • 低是最低的
  • 关闭是最后一个关闭
  • 卷只是卷的总和

但是问题很少:

  • 数据有差距(注意没有10:30:00排)
  • 5分钟的间隔必须在圆形时间开始,例如M5从10:25:00而不是10:22:00开始
  • 首先,可以省略不完整的集合,如本例所示,或包括在内(因此我们可以在10点20分进入5分钟)

关于上下采样Pandas文档给出了一个示例,但它们使用平均值作为上采样行的值,这在此处不起作用.我已经尝试使用groupbyagg,但无济于事.对于一个获得最高的最高和最低的低可能不是那么难,但我不知道如何获得第一次打开和最后关闭.

我尝试过的是:

grouped = slice.groupby( dr5minute.asof ).agg( 
    { 'Low': lambda x : x.min()[ 'Low' ], 'High': lambda x : x.max()[ 'High' ] } 
)
Run Code Online (Sandbox Code Playgroud)

但它导致以下错误,我不明白:

In [27]: grouped = slice.groupby( dr5minute.asof ).agg( { 'Low' : lambda x : x.min()[ 'Low' ], 'High' : lambda x : x.max()[ 'High' ] } )
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
/work/python/fxcruncher/<ipython-input-27-df50f9522a2f> in <module>()
----> 1 grouped = slice.groupby( dr5minute.asof ).agg( { 'Low' : lambda x : x.min()[ 'Low' ], 'High' : lambda x : x.max()[ 'High' ] } )

/usr/lib/python2.7/site-packages/pandas/core/groupby.pyc in agg(self, func, *args, **kwargs)
    242         See docstring for aggregate
    243         """
--> 244         return self.aggregate(func, *args, **kwargs)
    245 
    246     def _iterate_slices(self):

/usr/lib/python2.7/site-packages/pandas/core/groupby.pyc in aggregate(self, arg, *args, **kwargs)
   1153                     colg = SeriesGroupBy(obj[col], column=col,
   1154                                          grouper=self.grouper)
-> 1155                     result[col] = colg.aggregate(func)
   1156 
   1157             result = DataFrame(result)

/usr/lib/python2.7/site-packages/pandas/core/groupby.pyc in aggregate(self, func_or_funcs, *args, **kwargs)
    906                 return self._python_agg_general(func_or_funcs, *args, **kwargs)
    907             except Exception:
--> 908                 result = self._aggregate_named(func_or_funcs, *args, **kwargs)
    909 
    910             index = Index(sorted(result), name=self.grouper.names[0])

/usr/lib/python2.7/site-packages/pandas/core/groupby.pyc in _aggregate_named(self, func, *args, **kwargs)
    976             grp = self.get_group(name)
    977             grp.name = name
--> 978             output = func(grp, *args, **kwargs)
    979             if isinstance(output, np.ndarray):
    980                 raise Exception('Must produce aggregated value')

/work/python/fxcruncher/<ipython-input-27-df50f9522a2f> in <lambda>(x)
----> 1 grouped = slice.groupby( dr5minute.asof ).agg( { 'Low' : lambda x : x.min()[ 'Low' ], 'High' : lambda x : x.max()[ 'High' ] } )

IndexError: invalid index to scalar variable.
Run Code Online (Sandbox Code Playgroud)

因此,非常感谢任何帮助.如果我选择的路径不起作用,请建议其他相对有效的方法(我有数百万行).使用Pandas进行财务处理的一些资源也很不错.

And*_*rea 18

为了帮助其他用户使用更新版本的Pandas,有一种重新采样方法非常快速且有用来完成相同的任务:

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

df.resample('5T', how=ohlc_dict, closed='left', label='left')
Run Code Online (Sandbox Code Playgroud)

  • @RaduS,```df.resample('5T',closed ='left',label ='left').apply(ohlc_dict)``` (5认同)

Gar*_*ett 12

您的方法是合理的,但是失败了,因为应用于agg()的函数字典中的每个函数都接收一个Series对象,该对象反映了与键值匹配的列.因此,不必再次过滤列标签.有了这个,并假设groupby保留了顺序,你可以切片系列以提取打开/关闭列的第一个/最后一个元素(注意:groupby文档并不声称保留原始数据系列的顺序,但实际上似乎是这样.)

In [50]: df.groupby(dr5minute.asof).agg({'Low': lambda s: s.min(), 
                                         'High': lambda s: s.max(),
                                         'Open': lambda s: s[0],
                                         'Close': lambda s: s[-1],
                                         'Volume': lambda s: s.sum()})
Out[50]: 
                      Close    High     Low    Open  Volume
key_0                                                      
1999-01-04 10:20:00  1.1806  1.1819  1.1801  1.1801      34
1999-01-04 10:25:00  1.1789  1.1815  1.1776  1.1807      91
1999-01-04 10:30:00  1.1791  1.1792  1.1776  1.1780      16
Run Code Online (Sandbox Code Playgroud)

作为参考,这里是一个表,用于总结基于groupby对象类型的聚合函数的预期输入和输出类型以及聚合函数如何传递给agg().

                  agg() method     agg func    agg func          agg()
                  input type       accepts     returns           result
GroupBy Object
SeriesGroupBy     function         Series      value             Series
                  dict-of-funcs    Series      value             DataFrame, columns match dict keys
                  list-of-funcs    Series      value             DataFrame, columns match func names
DataFrameGroupBy  function         DataFrame   Series/dict/ary   DataFrame, columns match original DataFrame
                  dict-of-funcs    Series      value             DataFrame, columns match dict keys, where dict keys must be columns in original DataFrame
                  list-of-funcs    Series      value             DataFrame, MultiIndex columns (original cols x func names)
Run Code Online (Sandbox Code Playgroud)

从上表中,如果聚合需要访问多个列,则唯一的选择是将单个函数传递给DataFrameGroupBy对象.因此,完成原始任务的另一种方法是定义如下函数:

def ohlcsum(df):
    df = df.sort()
    return {
       'Open': df['Open'][0],
       'High': df['High'].max(),
       'Low': df['Low'].min(),
       'Close': df['Close'][-1],
       'Volume': df['Volume'].sum()
      }
Run Code Online (Sandbox Code Playgroud)

并使用agg():

In [30]: df.groupby(dr5minute.asof).agg(ohlcsum)
Out[30]: 
                       Open    High     Low   Close  Volume
key_0                                                      
1999-01-04 10:20:00  1.1801  1.1819  1.1801  1.1806      34
1999-01-04 10:25:00  1.1807  1.1815  1.1776  1.1789      91
1999-01-04 10:30:00  1.1780  1.1792  1.1776  1.1791      16
Run Code Online (Sandbox Code Playgroud)

虽然大熊猫未来可能会提供一些更清晰的内置魔法,但希望这能解释如何使用今天的agg()功能.


小智 5

df = df.resample('4h').agg({
    'open': lambda s: s[0],
    'high': lambda df: df.max(),
    'low': lambda df: df.min(),
    'close': lambda df: df[-1],
    'volume': lambda df: df.sum()
})
Run Code Online (Sandbox Code Playgroud)

  • 你好!为了改进这个答案,您可能希望添加一些关于其工作原理/原因的描述。 (4认同)