如何使用 rowwise 进行并行处理

Posted

技术标签:

【中文标题】如何使用 rowwise 进行并行处理【英文标题】:How to do parallel processing with rowwise 【发布时间】:2021-11-09 23:52:06 【问题描述】:

我正在使用rowwise 对每一行执行一个功能。这需要很长时间。为了加快速度,有没有办法使用并行处理,以便多个内核同时处理不同的行?

例如,我将 PRISM 天气数据 (https://prism.oregonstate.edu/) 汇总到州级,同时按人口加权。这是基于https://www.patrickbaylis.com/blog/2021-08-15-pop-weighted-weather/。

请注意,以下代码需要下载每日天气数据以及包含在非常小的地理区域的人口估计值的 shapefile。

library(prism)
library(tidyverse) 
library(sf)
library(exactextractr)
library(tigris)
library(terra)
library(raster)
library(ggthemes)

################################################################################
#get daily PRISM data
prism_set_dl_dir("/prism/daily/")
get_prism_dailys(type = "tmean", minDate = "2012-01-01", maxDate = "2021-07-31", keepZip=FALSE) 

Get states shape file and limit to lower 48    
states = tigris::states(cb = TRUE, resolution = "20m") %>%
    filter(!NAME %in% c("Alaska", "Hawaii", "Puerto Rico"))

setwd("/prism/daily")

################################################################################
#get list of files in the directory, and extract date
##see if it is stable (TRUE) or provisional data (FALSE)
list <- ls_prism_data(name=TRUE) %>% mutate(date1=substr(files, nchar(files)-11, nchar(files)-4), 
            date2=substr(product_name, 1, 11),
            year = substr(date2, 8, 11), month=substr(date2, 1, 3), 
            month2=substr(date1, 5, 6), day=substr(date2, 5, 6),
            stable = str_detect(files, "stable"))

################################################################################
#function to get population weighted weather by state

#run the population raster outside of the loop
# SOURCE: https://sedac.ciesin.columbia.edu/data/set/usgrid-summary-file1-2000/data-download - Census 2000, population counts for continental US
pop_rast = raster("/population/usgrid_data_2000/geotiff/uspop00.tif")
pop_crop = crop(pop_rast, states)

states = tigris::states(cb = TRUE, resolution = "20m") %>%
    filter(!NAME %in% c("Alaska", "Hawaii", "Puerto Rico"))

daily_weather <- function(varname, filename, date) 
    weather_rast = raster(paste0(filename, "/", filename, ".bil"))
    
    weather_crop = crop(weather_rast, states)
    
    pop_rs = raster::resample(pop_crop, weather_crop)
    
    states$value <- exact_extract(weather_crop, states, fun = "weighted_mean", weights=pop_rs)
    names(states)[11] <- varname
    
    states <- data.frame(states) %>% arrange(NAME) %>% dplyr::select(c(6,11))
    states


################################################################################
days <- list %>% rowwise() %>% mutate(states = list(daily_weather("tmean", files, date1))))

按原样,每行大约需要 7 秒。这加起来有 3500 行。我想得到除 tmean 之外的其他变量。因此,除非我能加快速度,否则将需要一天或更长时间才能完成所有工作。

我主要对能够将并行处理与 rowwise 一起使用的解决方案感兴趣,但我也欢迎有关如何以其他方式加速代码的其他建议。

【问题讨论】:

【参考方案1】:

您可以尝试purrr 的多处理等效furrrmap()pmap())。最快的方法是使用data.table。请参阅 this 博客文章,其中给出了我推荐背后的一些基准

【讨论】:

一个次要但重要的更正:它是“多处理”-而不是“多线程”。线程和进程之间存在重要差异,例如线程可以写入相同的内存/对象,但进程不能。

以上是关于如何使用 rowwise 进行并行处理的主要内容,如果未能解决你的问题,请参考以下文章

如何在pytorch中进行并行处理

使用 xgboost 和 caret 进行并行处理

使用 ProcessPoolExecutor 进行并行处理

如何进行两台计算机并行计算

使用 foreach 进行并行处理时出错:“找不到函数“%dopar%””

如何在 fasta 文件中并行化计算,其中每个处理器采用一个序列