pandas应用多个行的输入
我需要在一个数据表(dataframe)上进行操作,使用来自多行的数据。举个简单的例子,如果所有输入都来自同一行,我可以这样做:
df['c'] = df[['a','b']].apply(lambda x: awesome stuff, axis=1)
# or
df['d'] = df[['b','c']].shift(1).apply(...) # to get the values from the previous row
但是,如果我需要当前行的'a',以及上一行的'b',有没有办法用apply来实现呢?我可以添加一个新的'bshift'列,然后只用df[['a','bshift']],但我觉得应该有更直接的方法。
另外,关于访问数据表中特定值的事,有没有办法把带标签的索引和整数偏移结合起来?比如,我知道当前行的标签,但需要上一行的值。像这样df.at['labelIknow'-1, 'a']
(当然这是不行的)。这是在我必须逐行遍历的时候用的。提前谢谢你。
编辑:关于我在做什么的一些信息。我有一个包含OHLC(开盘、最高、最低、收盘)数据的pandas存储,每个证券对应一个表。在进行回测时,我会把需要的证券的完整日期范围加载到内存中,然后将其重新采样成适合当前测试的频率。接着,我会进行一些向量化操作,比如生成交易信号等。最后,我会从头到尾循环遍历数据,进行实际的回测,比如检查交易的进出、回撤等——我现在想加快的就是这个循环的部分。
2 个回答
对于第一部分,我觉得这样的事情是不太可能的。如果你能告诉我你具体想要实现什么,我可以更新我的回答。
再看看第二部分,你的数据结构似乎非常依赖于行的顺序。这通常不是管理数据库的好方法。如果你告诉我们你的整体目标是什么,我们可能会给你一些建议,帮助你找到解决方案(并且可能会有更好的数据结构方式)。
无论如何,如果你知道某个特定的索引标签,获取前一行的方法是:
df.ix[:'labelYouKnow'].iloc[-2]
请注意,这样做在效率上并不是最优的,所以你可能需要改善你的数据库结构,以避免需要这样操作。
这个回答直接解决了你的问题,让你可以使用apply,不过我不确定这是否比两行代码的解决方案更好。至少它避免了创建额外的变量。
df['c'] = pd.concat([ df['a'], df['a'].shift() ], axis=1).apply(np.mean,axis=1)
这段代码会把当前行和上一行'a'列的平均值放到'c'列里,比如说。
虽然这个方法不够通用,但对于简单的情况,你可以这样做(继续用平均值的例子):
df['c'] = ( df['a'] + df['a'].shift() ) / 2
这个方法在我小数据集上大约快了10倍。 我想如果你能用这种方式编码,速度应该是最快的。
你也可以考虑用stack()和层次索引来重塑数据。这是一种把所有变量放到同一行的方法,但我觉得这可能比concat方法或者通过shift()创建中间变量要复杂一些。