有没有办法加快Pandas的活动?

2024-09-26 04:42:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我知道矢量化函数是编写代码以提高速度的首选方法,但我无法找到一种方法来实现这个函数没有循环的功能。我用这种方式写函数的速度非常慢。(传递两个包含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

Tags: columnsinforindexsignalifvalix
1条回答
网友
1楼 · 发布于 2024-09-26 04:42:16

我相信.ix的实现在0.11中确实发生了变化。(http://pandas.pydata.org/pandas-docs/stable/whatsnew.html)不确定它是否相关。在

我在0.10.1上得到的一个快速加速是将tfunc更改为below以缓存正在更新的列/系列

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:
       sdf = df[col]
       for inum in range(1, len(df.index)):
           sdf.ix[inum] = 0 #np.nan
   return df

在我的机器上从~80到~9

相关问题 更多 >