株式会社ホクソエムのブログ

株式会社ホクソエムのブログ

クロネッカー積でデータを列方向(or行方向)に高速に複製もしくは定数倍する

r-wakalangからの転載です。以下のような質問がありました。

data.frameをカラム・ロウ方向に複製結合したdata.frameを出力させたいのですが、どうも綺麗に書けずです。。アドバイスお願いしますm( )m

この意味は、例えば「行方向に2個・列方向に3個複製」の場合は以下の図です。

f:id:StatModeling:20180824174855p:plain

データフレームが数値のみの場合、これは実はクロネッカー積と呼ばれる行列の特殊な積で表現できます。

  • Rで書く場合

Rではデフォルトで%x%関数(or kronecker関数)が用意されているのでそれを使えば簡単に実装できます。

B <- as.matrix(data.frame(a=1:3, b=4:6))
A <- matrix(1, nrow=2, ncol=3)
res <- A %x% B
  • Pythonで書く場合

Pythonでもnumpykronメソッドが用意されていますので、以下のように書くことができます。

import pandas as pd
import numpy as np

B = pd.DataFrame(np.arange(1,7).reshape(2,3).T, columns=list('ab'))
A = pd.DataFrame(np.ones((2,3)))

kp = pd.DataFrame(np.kron(A,B), columns=pd.MultiIndex.from_product([A,B]))

  * * *  

定数倍も行けます。例えば、以下のように

f:id:StatModeling:20180824163606p:plain

左のデータフレームから右のデータフレームが得たい場合です。

  • Rで書く場合
A <- as.matrix(data.frame(a=1:3, b=4:6))
B <- matrix(1:50, nrow=1)
res <- A %x% B
  • Pythonで書く場合
import pandas as pd
import numpy as np

A = pd.DataFrame(np.arange(1,7).reshape(2,3).T, columns=list('ab'))
B = pd.DataFrame(np.arange(1,51).reshape(1,50))

kp = pd.DataFrame(np.kron(A,B), columns=pd.MultiIndex.from_product([A,B]))

Enjoy!