Re: [問題] 請問有什麼辦法加快這個 for loop 嗎?
※ 引述《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
02/28 16:55, 1F
→
02/28 17:00,
6年前
, 2F
02/28 17:00, 2F
→
02/28 17:00,
6年前
, 3F
02/28 17:00, 3F
只是做個簡單的比較,用比較相近的 R and Python code,感謝大大提供更進階的方法
其實 R 速度也不輸給 Python
推
02/28 18:00,
6年前
, 4F
02/28 18:00, 4F
推
02/28 18:43,
6年前
, 5F
02/28 18:43, 5F
推
02/28 19:23,
6年前
, 6F
02/28 19:23, 6F
→
02/28 19:24,
6年前
, 7F
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
02/28 22:43, 8F
→
02/28 22:44,
6年前
, 9F
02/28 22:44, 9F
→
02/28 22:48,
6年前
, 10F
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
02/28 23:00, 13F
→
03/01 01:03,
6年前
, 14F
03/01 01:03, 14F
推
03/01 06:20,
6年前
, 15F
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
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
03/07 02:33, 22F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):