scipy 如果数据无法矢量化,迭代速度更快的替代方法

elcex8rz  于 2022-11-10  发布在  其他
关注(0)|答案(1)|浏览(148)

我在实现iterrows()时遇到了一个性能问题。

for _, row in df.iterrows():
    row["new_col"] = \
        df.apply(lambda x:some_func(row["col1"], ...), axis=1)

some_func()是一种复杂的函数,不能像SeriesDataFrame那样从同一行取需要某个特定值的输入。
但是,增加行数会使处理数据的时间呈指数增长,而不是呈线性增长。
有没有关于如何加快速度的建议?可能分成更小的组可能会改善,或者使用其他东西来代替iterrow()
如有任何意见,我们将不胜感激。
编辑1.

for count, row in df.iterrows():
    df.loc[count, "new_col"] = some_func(row["col1"], ... )
a9wyjsp7

a9wyjsp71#

为了进行测试,假设您的函数为:

def some_func(c1, c2, c3, c4, c5):
    return c2 + c4 + 100

将测试 DataFrame I定义为:

col1  col2  col3  col4  col5
0     1     2     3     4     5
1     6     7     8     9    10
2    11    12    13    14    15

如果您的函数既不能接收 DataFrame 也不能接收 Series,则可以编写一个“适配器函数”:

def myAdapter(row):
    return some_func(*row[:5])

我使用 [:5] 来允许DataFrame有一些“附加”列,然后仍然使用源行前5列的值来调用 some_func
要在 df 中生成新列,请运行:

df['new_col'] = df.apply(myAdapter, raw=True, axis=1)

raw=True导致传递给 myAdapter(当前行)的参数实际上作为 Numpy 数组而不是pandasonic Series 传递。
它的元素可以通过整数索引引用,并且在调用 some_func 时,可以执行“列表扩展”(row 的特许元素作为 some_func 的连续参数传递
对于我的测试数据,结果是:

col1  col2  col3  col4  col5  new_col
0     1     2     3     4     5      106
1     6     7     8     9    10      116
2    11    12    13    14    15      126

这样你至少有这样的好处,执行时间不会呈指数级增长。而且在我看来,它应该比你的代码执行得更快。

相关问题