簡體   English   中英

向量化迭代 function on Pandas DataFrame

[英]Vectorizing an iterative function on Pandas DataFrame

我有一個 dataframe,其中第一行是初始條件。

df = pd.DataFrame({"Year": np.arange(4),
                   "Pop": [0.4] + [np.nan]* 3})

和 function f(x,r) = r*x*(1-x) ,其中r = 2是常數, 0 <= x <= 1

我想通過逐行迭代地將 function 應用於Pop列來生成以下 dataframe。 df.Pop[i] = f(df.Pop[i-1], r=2)

df = pd.DataFrame({"Year": np.arange(4),
                   "Pop": [0.4, 0.48, 4992, 0.49999872]})

問題:是否有可能以矢量化的方式做到這一點?

我可以通過使用循環為 x 和 y 值構建列表來實現所需的結果,但這不是矢量化的。

我也試過這個,但所有nan地方都充滿了0.48

df.loc[1:, "Pop"] = R * df.Pop[:-1] * (1 - df.Pop[:-1])

以矢量化方式執行此操作是不可能的。

根據定義,矢量化利用並行處理來減少執行時間。 但是您問題中的所需值必須按順序計算,而不是並行計算。 有關詳細說明,請參閱此答案 df.expanding(2).apply(f)df.rolling(2).apply(f)這樣的東西是行不通的。

然而,獲得更高的效率是可能的。 您可以使用生成器進行迭代。 這是實現迭代過程的一個非常常見的結構。

def gen(x_init, n, R=2):
    x = x_init
    for _ in range(n):
        x = R * x * (1-x)
        yield x

# execute            
df.loc[1:, "Pop"] = list(gen(df.at[0, "Pop"], len(df) - 1))

結果:

print(df)
        Pop
0  0.400000
1  0.480000
2  0.499200
3  0.499999

小數據完全可以到此為止。 但是,如果 function 將執行很多次,您可以考慮使用numba優化生成器。

  • pip install numba or conda 首先在控制台conda install numba
  • import numba
  • 在生成器前面添加裝飾器@numba.njit

np.nan的個數改為 10^6 ,自己查看執行時間的差異。 在我的 Core-i5 8250U 64 位筆記本電腦上實現了從 468 毫秒到 217 毫秒的改進。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM