Re: [問題] 請問有什麼辦法加快這個 for loop 嗎?

看板Python作者 (123)時間6年前 (2018/02/28 15:47), 6年前編輯推噓8(8014)
留言22則, 8人參與, 6年前最新討論串2/2 (看更多)
※ 引述《CaptPlanet (ep)》之銘言: : 有list_a, list_b兩個list : list_a 有大約 70000 個 elements : list_b 大約 3 million 個 elements : 程式大致如下: : res_li = [] : for x in list_b: : try: : res_li.append(list_a.index(x)) : except: : res_li.append("") : 對 list_b 中的每一個 element : 在 list_a 中找到一樣 element 把他的 index 加到新的 list 中 : 隨著 iteration 增加 速度變得越來越慢, : 想請教各位為何會有這個現象以及有什麼方法加速這個 for loop 呢? : 謝謝各位高手 雖然這是 Python 版 我用 R 來比較一下速度 先講結論 使用小 data 測試速度, list_a = 7,000筆, list_b = 300,000筆 python 耗時 : 24.7 秒 R 使用平行運算(mclappy) 耗時 : 1.2 秒 R 使用單核運算( sapply ) 耗時 : 2.9 秒 #========================================== data 數量改為與原 po 相同, list_a = 70,000筆, list_b = 3,000,000筆 R 使用平行運算(mclappy) 耗時 : 69 秒 以下提供 code #========================================== # Python 版本 import numpy as np import random import time import datetime list_a = random.sample(range(0,10000),7000) list_b = random.sample(range(0,500000),300000) res_li = [] s = datetime.datetime.now() for x in list_b: try: res_li.append( list_a.index( x ) ) except: res_li.append("") t = datetime.datetime.now() - s print(t) # 0:00:24.748111 # 耗時 24s #========================================== # R 版本 library(data.table) library(dplyr) library(parallel) list_a = sample(c(0:10000),7000,replace = FALSE)# 7,000 list_b = sample(c(0:500000),300000,replace = FALSE)# 300,000 # case 1, 這裡使用 R 的多核心運算 res_li = c() s = Sys.time() res_li = mclapply(c(list_b),function(x){ if( x %in% list_a ){ map = which(list_a==x) #res_li = c(res_li,map) }else{ map = '' #res_li = c(res_li,map) } return(map) }, mc.cores=8, mc.preschedule = T) res_li = do.call(c,res_li) t = Sys.time() - s print(t) # Time difference of 1.229357 secs #=============================================== # case 2, 這裡使用一般單核運算 res_li = c() s = Sys.time() res_li = sapply(c(list_b),function(x){ if( x %in% list_a ){ map = which(list_a==x) #res_li = c(res_li,map) }else{ map = '' #res_li = c(res_li,map) } return(map) }) t = Sys.time() - s print(t) # Time difference of 2.913066 secs #=========================================== # 使用多核心, data 數與原 po 相同 list_a = sample(c(0:100000),70000,replace = FALSE)# 70,000 list_b = sample(c(0:5000000),3000000,replace = FALSE)# 3,000,000 res_li = c() s = Sys.time() res_li = mclapply(c(list_b),function(x){ if( x %in% list_a ){ map = which(list_a==x) #res_li = c(res_li,map) }else{ map = '' #res_li = c(res_li,map) } return(map) }, mc.cores=8, mc.preschedule = T) res_li = do.call(c,res_li) t = Sys.time() - s print(t) # Time difference of 1.151484 mins 提供不同的觀點參考參考 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 36.229.89.102 ※ 文章網址: https://www.ptt.cc/bbs/Python/M.1519804063.A.817.html

02/28 16:55, 6年前 , 1F
R用八個核心結果比單核只快2倍多,怪怪的
02/28 16:55, 1F

02/28 17:00, 6年前 , 2F
而且R可以直接用match做
02/28 17:00, 2F

02/28 17:00, 6年前 , 3F
甚至是fastmatch::fmatch都可以很快
02/28 17:00, 3F
只是做個簡單的比較,用比較相近的 R and Python code,感謝大大提供更進階的方法 其實 R 速度也不輸給 Python

02/28 18:00, 6年前 , 4F
python將list a 改成dict,速度比R還快...
02/28 18:00, 4F

02/28 18:43, 6年前 , 5F
同樓上 BigO比一下就知道了
02/28 18:43, 5F

02/28 19:23, 6年前 , 6F
對R沒偏見,語法較python簡潔且內建支援矩陣,但原生R真的
02/28 19:23, 6F

02/28 19:24, 6年前 , 7F
大部分情況都比python慢.
02/28 19:24, 7F
根據 celestialgod 大 跟 vfgce 大的意見進行修正 以下是 R and Python code #================================== # python import random import datetime list_a = random.sample(range(0,100000),70000) list_b = random.sample(range(0,5000000),3000000) list_a = { i:list_a[i] for i in range(len(list_a))} res_li = [] s = datetime.datetime.now() for x in list_b: res_li.append( list_a.get(x,'') ) t = datetime.datetime.now() - s print(t) # 0:00:01.056265 #================================== # R install.packages('fastmatch') library(fastmatch) list_a = sample(c(0:100000),70000,replace = FALSE) list_b = sample(c(0:5000000),3000000,replace = FALSE) s = Sys.time() res_li = fmatch(list_b,list_a, nomatch = -1) res_li[res_li==-1]='' t = Sys.time() - s print(t) # Time difference of 0.5497556 secs PS : 單純做個比較,兩個語言各有優缺點,多會一點也不壞 ※ 編輯: f496328mm (36.229.89.102), 02/28/2018 19:48:51

02/28 22:43, 6年前 , 8F
語言這種問題是戰不完的 單純要拼這種速度可以拉C/C++
02/28 22:43, 8F

02/28 22:44, 6年前 , 9F
FORTRAN Rust go..........還是看要應用而定
02/28 22:44, 9F

02/28 22:48, 6年前 , 10F
如果這種計算不多 並且是要做web app呢?
02/28 22:48, 10F

02/28 22:53, 6年前 , 11F
不是要拚速度拉 只是提供一個參考
02/28 22:53, 11F

02/28 22:59, 6年前 , 12F
如果是作分析/統計 多參考是沒錯的,但是要做到產品階段
02/28 22:59, 12F

02/28 23:00, 6年前 , 13F
還是要考慮不同語言的應用場景XDXDXD
02/28 23:00, 13F

03/01 01:03, 6年前 , 14F
這到底能參考到什麼我實在是看不出來
03/01 01:03, 14F

03/01 06:20, 6年前 , 15F
如果能說明R版本的方法或概念如何改進python版本比較好
03/01 06:20, 15F

03/01 06:20, 6年前 , 16F
,不然看起來是在拼語言
03/01 06:20, 16F

03/01 07:44, 6年前 , 17F
研究分析你想用什麼語言都行,但是這樣的效能差距,應該還
03/01 07:44, 17F

03/01 07:44, 6年前 , 18F
不足達到轉換語言的程度,更何況這段py code還可再修改會
03/01 07:44, 18F

03/01 07:44, 6年前 , 19F
更快的可能。所以:參考不到什麼+看起來就是在拼速度(無誤
03/01 07:44, 19F

03/01 07:44, 6年前 , 20F
)
03/01 07:44, 20F

03/06 05:15, 6年前 , 21F
03/06 05:15, 21F

03/07 02:33, 6年前 , 22F
可以參考出python比R語言慢很多啊
03/07 02:33, 22F
文章代碼(AID): #1QbbwVWN (Python)
文章代碼(AID): #1QbbwVWN (Python)