我知道矢量化函数是编写代码以提高速度的首选方法,但我无法找到一种方法来实现这个函数没有循环的功能。我用这种方式写函数的速度非常慢。(传递两个包含100列和2000行的数据帧作为参数,此函数需要100秒才能完成。我只希望再等一秒钟。)
def gen_fuzz_logic_signal(longp, shortp):
# Input dataframes should have 0, -1, or 1 value
flogic_signal = pd.DataFrame(index = longp.index, columns = longp.columns)
for sym in longp.columns:
print sym
prev_enter = 0
for inum in range(0, len(longp.index)):
cur_val = np.nan
if longp.ix[inum, sym] == 0 and prev_enter == +1:
cur_val = 0.5
if shortp.ix[inum, sym] == 0 and prev_enter == -1:
cur_val = -0.5
if longp.ix[inum, sym] == 1 and shortp.ix[inum, sym] == -1:
if longp.ix[inum - 1, sym] != 1:
cur_val = 1
prev_enter = 1
elif shortp.ix[inum - 1, sym] != -1:
cur_val = -1
prev_enter = -1
else:
cur_val = prev_enter
else:
if longp.ix[inum, sym] == 1:
cur_val = 1
prev_enter = 1
if shortp.ix[inum, sym] == -1:
cur_val = -1
prev_enter = -1
flogic_signal.ix[inum, sym] = cur_val
return flogic_signal
函数的输入只是两个值为1、-1或0的数据帧。如果有人对如何将其矢量化或加速,我将非常感激。我试着用“[sym][inum]”替换“.ix[inum,sym]”,但速度更慢。在
^{pr2}$编辑:
我只是重新运行了一些旧代码,它们在pandas数据帧中使用类似的循环来设置值。以前可能需要5秒,现在我看到可能要花100倍。我想知道这个问题是不是因为最近版本的熊猫发生了变化。这是我能想到的唯一的变化。请参阅下面的代码。使用Pandas 0.11在我的计算机上运行需要73秒。对于一个非常基本的函数来说,这似乎是非常缓慢的,尽管它是按元素操作的,但是仍然是。如果有人有机会的话,我很想知道下面这些在你的电脑和你的熊猫版本上要花多长时间。在
import time
import numpy as np
import pandas as pd
def timef(func, *args):
start= time.clock()
for i in range(2):
func(*args)
end= time.clock()
time_complete = (end-start)/float(2)
print time_complete
def tfunc(num_row, num_col):
df = pd.DataFrame(index = np.arange(1,num_row), columns = np.arange(1,num_col))
for col in df.columns:
for inum in range(1, len(df.index)):
df.ix[inum, col] = 0 #np.nan
return df
timef(tfunc, 1000, 1000) <<< This takes 73 seconds on a Core i5 M460 2.53gz Windows 7 laptop.
编辑2 7-9-13下午1:23:
我找到了一个临时的解决办法!我把代码改成了下面的代码。实际上,将每个列转换为ndarray,然后在python列表中组装新列,然后再将其插入新pandas数据帧中的列中。用上面的旧版本做50列,大约2000行,用了101秒。以下版本只需0.19秒!对我来说足够快了。不知道为什么。ix太慢了。就像我上面说的,在熊猫的早期版本中,我相信元素操作要快得多。在
def gen_fuzz_logic_signal3(longp, shortp):
# Input dataframes should have 0 or 1 value
flogic_signal = pd.DataFrame(index = longp.index, columns = longp.columns)
for sym in longp.columns:
coll = longp[sym].values
cols = shortp[sym].values
prev_enter = 0
newcol = [None] * len(coll)
for inum in range(1, len(coll)):
cur_val = np.nan
if coll[inum] == 0 and prev_enter == +1:
cur_val = 0.5
if cols[inum] == 0 and prev_enter == -1:
cur_val = -0.5
if coll[inum] == 1 and cols[inum] == -1:
if coll[inum -1] != 1:
cur_val = 1
prev_enter = 1
elif cols[inum-1] != -1:
cur_val = -1
prev_enter = -1
else:
cur_val = prev_enter
else:
if coll[inum] == 1:
cur_val = 1
prev_enter = 1
if cols[inum] == -1:
cur_val = -1
prev_enter = -1
newcol[inum] = cur_val
flogic_signal[sym] = newcol
return flogic_signal
我相信.ix的实现在0.11中确实发生了变化。(http://pandas.pydata.org/pandas-docs/stable/whatsnew.html)不确定它是否相关。在
我在0.10.1上得到的一个快速加速是将tfunc更改为below以缓存正在更新的列/系列
在我的机器上从~80到~9
相关问题 更多 >
编程相关推荐