Python: Pandas: 加速 Apply 函数

1 投票
1 回答
1395 浏览
提问于 2025-04-18 15:13

我正在尝试对一个33MB的CSV格式的数据表使用pandas的apply函数,但速度非常慢。我想弄清楚原因。我之前对一个更大的数据表(16GB)使用apply,花了大约6个小时就完成了。而现在这个小得多的数据表,我让它运行了1.5个小时,结果还是没有任何进展。

我在想,可能是哪里出了问题。我怀疑是因为我使用了datareader函数,它需要连接到Yahoo或Google财经,这可能导致速度变慢。不过,当我用它对几个股票进行测试时,速度似乎很快。

有没有人对此有什么想法?或者有什么方法可以让它运行得更快?我考虑过使用cython,但如果问题出在连接时间上,那样也不会提高太多速度。更好的是,有没有办法让这个过程向量化?(我暂时想不到办法,但有些人比我聪明得多 :))我问了很多问题,基本上就是想找一些建议,让这个运行得更快。谢谢!

另外,如果有人知道如何在apply函数中添加进度条,那就更好了 :) 再次感谢!

data4=pd.read_csv('check2.csv', parse_dates=['dater1','dater2'], infer_datetime_format=True)

def nextweekday(date):
    day=date.weekday()
    if day==4:
        return date+datetime.timedelta(days=3)
    if day==5:
        return date+datetime.timedelta(days=2)
    else:
        return date+datetime.timedelta(days=1)

def getquote(tick,date,plus):
    date=date+datetime.timedelta(days=plus)
    nextday=nextweekday(date)
    try:
        return DataReader(tick, "yahoo",date, nextday)["Close"]
    except:
        return "NO"

def apply_days5(row):
    return getquote(row['AcquirorTickerSymbol'],row['dater2'],5)

data4['days5']=data4.apply(apply_days5, axis=1)

1 个回答

1

我不太确定你想要实现什么,但我有几个想法。

首先,像这样频繁地请求雅虎的数据会增加很多不必要的负担。我可能会这样做,把所有的股票数据读入一个数据框中。

In [83]: tickers = data4['AcquirorTickerSymbol'].unique()

In [84]: min_date = data4['dater2'].min()
    ...: max_date = data4['dater2'].max()
    ...:     
    ...: dfs = []
    ...: for ticker in tickers:
    ...:     df = DataReader(ticker, 'yahoo', min_date, max_date)[['Close']]
    ...:     df['AcquirorTickerSymbol'] = ticker
    ...:     df['dater2'] = df.index
    ...:     dfs.append(df)

In [85]: stock_df = pd.concat(dfs, ignore_index=True)

然后,不用apply这个方法,你可以把已有的数据和股票数据框合并,像这样:

In [92]: data4 = data4.merge(stock_df, how='left')

如果你想填补缺失的值,和在apply里写复杂的逻辑相比,使用 fillna 会快得多。

In [94]: data4['Close'] = data4['Close'].fillna('NO')

撰写回答