[英]R: Speed up a for loop on a very large data frame?
我有一組巨大的坐標和相關的Z值。 一些坐標對用不同的Z值重復幾次。 我想獲得每個唯一坐標對的所有Z值的平均值。
我寫了一小段代碼,在小數據幀上完美運行。 問題是我的實際數據幀有超過2百萬行,計算完成時間大於10個小時。 我想知道是否有辦法讓它更有效率並減少計算時間。
這是我的df的樣子:
> df
x y Z xy
1 -54.60417 4.845833 0.3272980 -54.6041666666667/4.84583333333333
2 -54.59583 4.845833 0.4401644 -54.5958333333333/4.84583333333333
3 -54.58750 4.845833 0.5788663 -54.5875/4.84583333333333
4 -54.57917 4.845833 0.6611844 -54.5791666666667/4.84583333333333
5 -54.57083 4.845833 0.7830828 -54.5708333333333/4.84583333333333
6 -54.56250 4.845833 0.8340629 -54.5625/4.84583333333333
7 -54.55417 4.845833 0.8373666 -54.5541666666667/4.84583333333333
8 -54.54583 4.845833 0.8290986 -54.5458333333333/4.84583333333333
9 -54.57917 4.845833 0.9535526 -54.5791666666667/4.84583333333333
10 -54.59583 4.837500 0.0000000 -54.5958333333333/4.8375
11 -54.58750 4.845833 0.8582580 -54.5875/4.84583333333333
12 -54.58750 4.845833 0.3857006 -54.5875/4.84583333333333
您可以看到一些xy坐標是相同的(例如,行3,11,12或4和9),我想要所有這些相同坐標的平均Z值。 所以這是我的腳本:
mean<-vector(mode = "numeric",length = length(df$x))
for (i in 1:length(df$x)){
mean(df$Z[which(df$xy==df$xy[i])])->mean[i]
}
mean->df$mean
df<-df[,-(3:4)]
df<-unique(df)
我得到這樣的東西:
> df
x y mean
1 -54.60417 4.845833 0.3272980
2 -54.59583 4.845833 0.4401644
3 -54.58750 4.845833 0.6076083
4 -54.57917 4.845833 0.8073685
5 -54.57083 4.845833 0.7830828
6 -54.56250 4.845833 0.8340629
7 -54.55417 4.845833 0.8373666
8 -54.54583 4.845833 0.8290986
10 -54.59583 4.837500 0.0000000
這樣做是可行的,但是肯定有一種方法可以加速這個過程(可能沒有for循環)的df有更多的行數?
歡迎! 在將來,最好為我們提供一種快速方式來復制和粘貼一些代碼,這些代碼生成您正在使用的數據集的基本功能。 這是我想的一個例子:
DF <- data.frame(x = sample(c(-54.1, -54.2), size = 10, replace = TRUE),
y = sample(c(4.8, 4.4), size = 10, replace = TRUE),
z = runif(10))
這看起來只是一個拆分應用組合方法:
set.seed(1)
df <- data.frame(x = sample(c(-54.1, -54.2), size = 10, replace = TRUE),
y = sample(c(4.8, 4.4), size = 10, replace = TRUE),
z = runif(10))
library(data.table)
DT <- as.data.table(df)
DT[, .(mean_z = mean(z)), keyby = c("x", "y")]
#> x y mean_z
#> 1: -54.2 4.4 0.3491507
#> 2: -54.2 4.8 0.4604533
#> 3: -54.1 4.4 0.3037848
#> 4: -54.1 4.8 0.5734239
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:data.table':
#>
#> between, first, last
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
df %>%
group_by(x, y) %>%
summarise(mean_z = mean(z))
#> # A tibble: 4 x 3
#> # Groups: x [?]
#> x y mean_z
#> <dbl> <dbl> <dbl>
#> 1 -54.2 4.4 0.349
#> 2 -54.2 4.8 0.460
#> 3 -54.1 4.4 0.304
#> 4 -54.1 4.8 0.573
由reprex包創建於2018-09-21(v0.2.1)
你可以嘗試dplyr::summarise
。
library(dplyr)
df %>%
group_by(x, y) %>%
summarise(meanZ = mean(Z))
我想這可能需要不到一分鍾,具體取決於你的機器。
其他人可能會提供data.table
答案,這可能會更快。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.