簡體   English   中英

改善非常慢的python代碼的執行時間

[英]Improve execution time of very slow python code

這是我的第一篇文章,所以請耐心等待。 我需要一些幫助來優化下面的一個襯墊。

pd_df.loc[flag, 'COL_{}'.format(col_number)] = pd_df.loc[flag,'COL{}'.format(col_number)].apply(lambda x: x + str(userid) + "@")

pd_df : Panda 數據框包含 2M 行

flag= numpy 一維布爾數組,用於在 pd_df 中一次過濾/更新多行

COL_{}'.format(col_number)= 根據主 FOR 循環的隨機列號,如 COL_1,COL_5 到 COL_15(5000 個字符長度的數據類型字符串)

一般來說,這段代碼是做什么的,首先根據列號根據要更新的標志和列過濾要更新的行,並以@作為分隔符在這些多行和單列中附加用戶ID列表。 例如@userid1@userid2@userid2 等等。

由於 Pandas 數據幀 loc 函數緩慢且行數很大,即 2M,這行代碼占用了我總時間的 75%。

有人可以幫我把這部分轉換成更優化的方式,比如字典/numpy 數據類型。

下面是上面代碼正在創建的輸出。 根據相關的 Country 和 Category 用戶 ID,將其用戶 ID 附加到該列號。 假設 Col_1 可以包含最多 userid3 和 column2 最多 userid7 等等,直到 col15。

在此處輸入圖片說明

提前致謝。

問候, 麗瓦

同意apply()可能很慢。 您希望盡可能利用矢量化操作。 嘗試使用連接運算符 ( + )。 這是否工作得更快

pd_df.loc[flag, 'COL_{}'.format(col_number)] = pd_df.loc[flag,'COL{}'.format(col_number)] + (str(userid) + "@")

此外,不確定它是否會有所幫助,但是應該預先計算其中一些字符串(可能 Python 已經緩存它們,但以防萬一):

col_name = 'COL_{}'.format(col_number)
suffix = str(userid) + "@"
pd_df.loc[flag, col_name] = pd_df.loc[flag, col_name] + suffix

幾點:

  1. f-strings總是比str.format快,盡可能使用它們:

     In [3]: fmt = "{foo}" In [4]: %timeit fmt.format(foo=5) 299 ns ± 21.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) In [5]: foo = 5 In [6]: %timeit f"{foo}" 79.2 ns ± 2.31 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
  2. 似乎userid獨立於數據幀,我不確定您為什么使用apply ,只需使用broadcast

     In [8]: userid = "abcdef" In [9]: pd.Series('abc def ghi jkl'.split()) + f'@{userid}' Out[9]: 0 abc@abcdef 1 def@abcdef 2 ghi@abcdef 3 jkl@abcdef dtype: object

所以最后的方法可能是這樣的:

for num in range(5):
    flag = ... # calculate flag
    df[flag, f"col_{num}"] = df[flag, f"col_{num}"] + f"@{userid}"

apply是按項目運行函數的較慢方法之一。

pd_df.loc[flag, f’COL_{col_number}’] = pd_df.loc[flag, f’COL_{col_number}’].map(lambda x: f’{x}{userid}@‘)

暫無
暫無

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

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