【R言語】統計解析フリーソフトR 第6章【GNU R】 [無断転載禁止]©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
array(1:48, dim=c(6, 4, 2))
を,3行2列おきに平均して
,,1
[,1] [,2]
[1,] 5 17
[2,] 8 20
,,2
[,1] [,2]
[1,] 29 41
[2,] 32 44
としたいんですが,効率的な方法はないでしょうか。
実際のデータは,10000x10000x400なんです。 >>154
>3行2列
さっぱりわからん。
例えば、結果の[1,1,1]の5は、どれとどれの平均? >>155
6行4列の左上の6つ1,2,3,7,8,9の平均5だと思う。 >>154
効率的かどうかはわからんが、やってみた
(d=array(1:48, dim=c(6, 4, 2)))
a=3
b=2
l=6
m=4
n=2
re=NULL
for(k in 1:n){
for(j in 1:(m/b)){
for(i in 1:(l/a)){
re=append(re,mean(d[1:3+3*(i-1),1:2+2*(j-1),k]))
}
}
}
array(re,dim=c(m/b,l/a,n)) >>155
>>154です。
説明が悪くてすみません。
>>156の通りです。 >>157
ありがとうございます。
手元にデータがないので明日試してみます。 なるほど、じゃあその5,8,17,20はこういうことか。
> a <- array(1:48, dim=c(6, 4, 2))
> b <- expand.grid(1:(dim(a)[1] %/% 3), 1:(dim(a)[2] %/% 2))
> f <- function(i, j, k=1){mean(a[(3*i-2):(3*i),(2*j-1):(2*j),k])}
> mapply(f, b[,1], b[,2])
[1] 5 8 17 20 あぁ、すでに >>157 が回答を書いていたorz > d=array(1:48, dim=c(6, 4, 2))
> a=3
> b=2
> l=6
> m=4
> n=2
> re=NULL
> for(k in 1:n){
+ for(j in 1:(m/b)){
+ for(i in 1:(l/a)){
+ re=append(re,mean(d[1:a+a*(i-1),1:b+b*(j-1),k]))
+ }
+ }
+ }
> array(re,dim=c(m/b,l/a,n))
, , 1
[,1] [,2]
[1,] 5 17
[2,] 8 20
, , 2
[,1] [,2]
[1,] 29 41
[2,] 32 44
データは10000x10000x400なら
l=10000
m=10000
n=400
でよくね? 最初の1行で
> d=array(1:(10000*10000*400))
Error: cannot allocate vector of size 298.0 Gb
エラーがでたw 正しいエラーwはこっち
> d=array(1:(10000*10000*400),dim=c(6, 4, 2))
Error: cannot allocate vector of size 298.0 Gb そもそも、10000x10000x400だと10000行は3行にならないな。最終行を無視して9999行にするのかな? >160を参考に>157のforだらけのスパゲティー・ソースを(ちょっと一般化して)改変しました。
(変数名の重複を避けるため>160の変数名は変更してあります。)
> a=3
> b=2
> c=1
>
> l=6
> m=4
> n=2
>
> A <- array(1:48, dim=c(l,m,n))
> B <- expand.grid(1:(l %/% a), 1:(m %/% b),1:(n %/% c))
> f <- function(i, j, k){mean(A[(a*(i-1)+1):(a*i),(b*(j-1)+1):(b*j),(c*(k-1)+1):(c*k)])}
> re=mapply(f, B[,1], B[,2],B[,3])
> array(re,dim=c(m%/%b,l%/%a,n%/%c))
, , 1
[,1] [,2]
[1,] 5 17
[2,] 8 20
, , 2
[,1] [,2]
[1,] 29 41
[2,] 32 44
>
上級者のコードを読むのは勉強になります。(深謝) 先輩方,>>154です。
巨細にわたってご教示・ご議論いただきありがとうございました。
>>166のコードを参考にして,無事処理することができました。
実行速度も申し分なく,効率的に作業が進められそうです。
今回は私には目から鱗な解法で,勉強になりました。
質問して良かったと思っています。。本当にありがとうございました。
10,000行の扱いですが,3行ごとに処理して1行無視してもよいし,
4から7行程度で処理してもよく,フレキシブルです。
今回は4行にして余りなしにしました。 処理速度を比べてみた。
fs<-function(){ #スパゲッティ・ソース
d=array(1:(l*m*n),dim=c(l,m,n))
re=NULL
for(k in 1:(n/c)){
for(j in 1:(m/b)){
for(i in 1:(l/a)){
re=append(re,mean(d[1:a+a*(i-1),1:b+b*(j-1),1:c+c*(k-1)]))
}}}
array(re,dim=c(m/b,l/a,n))
}
fe <- function(){ # Expertソース
A <- array(1:(l*m*n), dim=c(l,m,n))
B <- expand.grid(1:(l %/% a), 1:(m %/% b),1:(n %/% c))
f <- function(i, j, k){mean(A[(a*(i-1)+1):(a*i),(b*(j-1)+1):(b*j),(c*(k-1)+1):(c*k)])}
re=mapply(f, B[,1], B[,2],B[,3])
array(re,dim=c(m%/%b,l%/%a,n%/%c))
}
a=4
b=2
c=1
l=400
m=200
n=2
> system.time(fs())
user system elapsed
2.17 0.00 2.18
> system.time(fe())
user system elapsed
1.14 0.00 1.14
>160氏のスキルに改めて感服。 # 既約剰余類群 (Z/nZ)*
kjrg <- function(n){
nn=0:(n-1)
f=function(x,y) (x*y)%%n
names(nn)=paste0('n',nn)
z=outer(nn,nn,f)
idx=which(gmp::gcd(1:(n-1),n)==1)+1
return(z[idx,idx])
}
kjrg(10)
kjrg(15)
kjrg(24)
> kjrg(24)
n1 n5 n7 n11 n13 n17 n19 n23
n1 1 5 7 11 13 17 19 23
n5 5 1 11 7 17 13 23 19
n7 7 11 1 5 19 23 13 17
n11 11 7 5 1 23 19 17 13
n13 13 17 19 23 1 5 7 11
n17 17 13 23 19 5 1 11 7
n19 19 23 13 17 7 11 1 5
n23 23 19 17 13 11 7 5 1 # 既約剰余類群での加減乗除
n=24
n_star=which(gmp::gcd(1:(n-1),n)==1) ; n_star
tasu <- function(x,y) (x+y)%%n
hiku <- function(x,y) (x-y)%%n # row - col
kake <- function(x,y) (x*y)%%n
g=function(x) n_star[which(x==1)]
.M=outer(n_star,n_star,kake)
G=apply(.M,2,g)
gyaku <- function(x) n_star[which(G==(x%%n))]
waru <- function(x,y) (x*gyaku(y))%%n # row ÷ col
xx=yy=c(0,n_star)
names(xx)=paste0('x',c(0,n_star))
names(yy)=paste0('y',c(0,n_star))
outer(xx,yy,tasu) # x + y
outer(xx,yy,hiku) # x - y
outer(xx,yy,kake) # x * y
X=Y=n_star #outer(X,Y,waru) # WRONG!!
a=expand.grid(X,Y)
b=matrix(mapply(waru,a[,1],a[,2]),length(X))
rownames(b)=paste0('x',n_star)
colnames(b)=paste0('y',n_star)
b # x / y ■ このスレッドは過去ログ倉庫に格納されています