[英]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
幾點:
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)
似乎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.