2016-10-15 12 views
0

質問:以下のタスクをより効率的に実行するにはどうすればよいですか?

私の問題は次のとおりです。私は実際の物理空間(x、y、z)にポイントの(大きな)3Dデータセットを持っています。それはこのようになり、そのループのネストされたことにより、生成された:別のデータセットと比較することのためにPython - 特定のループ命令で生成されたデータを反転する

# Generate given dat with its ordering 
x_samples = 2 
y_samples = 3 
z_samples = 4 
given_dat = np.zeros(((x_samples*y_samples*z_samples),3)) 
row_ind = 0 
for z in range(z_samples): 
    for y in range(y_samples): 
     for x in range(x_samples): 
      row = [x+.1,y+.2,z+.3] 
      given_dat[row_ind,:] = row 
      row_ind += 1 
for row in given_dat: 
    print(row)` 

、私は(非正統的な次のように私の希望順に与えられたデータを並べ替えしたい、私は)知っている:

# Generate data with desired ordering 
x_samples = 2 
y_samples = 3 
z_samples = 4 
desired_dat = np.zeros(((x_samples*y_samples*z_samples),3)) 
row_ind = 0 
for z in range(z_samples): 
    for x in range(x_samples): 
     for y in range(y_samples): 
      row = [x+.1,y+.2,z+.3] 
      desired_dat[row_ind,:] = row 
      row_ind += 1 
for row in desired_dat: 
    print(row) 

私が欲しいものを行う関数を書かれているが、それは恐ろしく遅く、非効率的である:

def bad_method(x_samp,y_samp,z_samp,data): 
    zs = np.unique(data[:,2]) 
    xs = np.unique(data[:,0]) 
    rowlist = [] 
    for z in zs: 
     for x in xs: 
      for row in data: 
       if row[0] == x and row[2] == z: 
       rowlist.append(row) 
    new_data = np.vstack(rowlist) 
    return new_data 
# Shows that my function does with I want 
fix = bad_method(x_samples,y_samples,z_samples,given_dat)  
print('Unreversed data') 
print(given_dat) 
print('Reversed Data') 
print(fix) 
# If it didn't work this will throw an exception 
assert(np.array_equal(desired_dat,fix)) 

それが高速ですので、どのように私は私の機能を向上させることができますか?私のデータセットは、通常約200万行あります。私はより速くなると確信しているいくつかの賢いスライシング/インデックス作成でこれを行うことが可能でなければなりませんが、どうやってどのように考えているのか分かりません。助けてくれてありがとう!

答えて

2

あなたの配列の形を変えることができ、軸は、必要に応じて交換し、再び再構築:

# (No need to copy if you don't want to keep the given_dat ordering) 
data = np.copy(given_dat).reshape((z_samples, y_samples, x_samples, 3)) 
# swap the "y" and "x" axes 
data = np.swapaxes(data, 1,2) 
# back to 2-D array 
data = data.reshape((x_samples*y_samples*z_samples,3)) 

assert(np.array_equal(desired_dat,data)) 
+0

ブリリアント!しかし、私はかなりうまくやっています。私は非常に視覚的な人間なので、このようなことを理解しようとすると視覚的な配列に役立つことがよくあります。つまり、4次元配列を作ったのですよね? –

+0

Yup - 3つのアイテムの各行は、再構成された配列の(z、y、x)位置によってインデックスされるため、軸1と2を交換すると、(z、x、y)あなたにあなたが望む順序を与えます。 – xnx

+0

さて、お詫びしますが、私はまだかなり混乱しています。 4番目の軸に沿って3つの要素を使用することをどのように知っていましたか?私は3つの3Dブロックとしてこれを視覚化しています。だから、私はコールシグネチャを意味することを理解しています:reshape( "レイヤーの行"、 "レイヤーの列"、 "ブロックのレイヤー"、 "ブロックの数")これは理にかなっていますか? –

関連する問題