質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

2回答

2749閲覧

numpy (python) でボクセル値を高速に取得する方法を教えてください

fuji_san

総合スコア0

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/03/07 04:02

イメージ説明

いま2つの配列 coordinate と voxel があるとします。
voxelは三次元配列 (512,512,512) でそれぞれにボクセル値を持っています。
coordinateは二次元配列 (512,512) で今から取得したいボクセル値の座標が三次元のリストとして格納されています。

このcoordinateは、いわゆる斜め掛けの座標を保持しているため、例えばvoxel[:,:,512] のようにして任意の座標軸のボクセル値を一度に取得できないと考えています。

私は以下のようなコードを書いて二次元配列 imgAry (512, 512) に任意の座標のボクセル値を格納させましたが、より高速なコードがあるなら教えて頂きたいです。よろしくお願いします。

import numpy as np
imgAry = np.array( [voxel[ j[0], j[1], j[2] ] for j in coordinate ] ).reshape(512, 512)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kirara0048

2021/03/08 02:01

`coordinate`は、「リストを要素にもつndarray」ということですか? `np.concatenate(coordinate).shape`は`(262144, 3)`になりますか? `coordinate`の要素が`[x, y, z]`であるとき、それを`voxel[x, y, z]`の値に置換する、という認識であってますか?
fuji_san

2021/03/13 07:55

ご質問ありがとうございます。 >> `coordinate`は、「リストを要素にもつndarray」ということですか? おっしゃる通りです。 >> `np.concatenate(coordinate).shape`は`(262144, 3)`になりますか? 上図にミスがありました。coordinate.shape が (262144, 3)になります。 よって np.concatenate(coordinate).shape は (786432,) になります。 `coordinate`の要素が`[x, y, z]`であるとき、それを`voxel[x, y, z]`の値に置換する、という認識であってますか? おっしゃる通りです。
bsdfan

2021/03/14 00:43

多次元のndarrayを使うのではなく、リストを要素に持つndarrayを使う理由がありますか? 速度を重視するならndarrayだけでやる方が良さそうですが。
guest

回答2

0

いまいち状況がよくわかっていませんが……

python

1# 2voxel[coordinate[:, 0], coordinate[:, 1], coordinate[:, 2]]

coordinateが (262144, 3)形状の整数データ型配列なのであれば、上記で (262144,)形状のndarrayが出力され、以下で求める形になるはずです。

python

1voxel[coordinate[:, 0], coordinate[:, 1], coordinate[:, 2]].reshape(512, 512)

投稿2021/03/13 16:52

kirara0048

総合スコア1399

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

512の例を出すのは訳が分からなくなるので4に縮小します。各boxelの値は、RGBを想定しています。
512のときは、N=512にしてください。

まずサンプルデータを作ります。
voxelです。

python

1>>> import numpy as np 2>>> import random 3>>> 4>>> N = 4 5>>> voxel = np.zeros(N*N*N, dtype=object) 6>>> for i in range(N*N*N): 7... voxel[i] = [random.randint(0,255) for i in range(3)] 8... 9>>> voxel = voxel.reshape(N,N,N) 10>>> print(voxel) 11[[[list([149, 18, 49]) list([220, 1, 186]) list([168, 111, 239]) 12 list([105, 140, 107])] 13 [list([110, 181, 29]) list([203, 197, 147]) list([185, 157, 219]) 14 list([133, 123, 114])] 15 [list([198, 89, 152]) list([131, 62, 104]) list([12, 185, 234]) 16 list([88, 82, 84])] 17 [list([138, 215, 119]) list([136, 117, 121]) list([158, 98, 121]) 18 list([13, 181, 209])]] 19 20 [[list([172, 0, 153]) list([132, 39, 155]) list([105, 190, 101]) 21 list([240, 192, 199])] 22 [list([38, 254, 24]) list([9, 69, 173]) list([211, 89, 210]) 23 list([223, 159, 43])] 24 [list([42, 92, 125]) list([101, 194, 24]) list([134, 215, 16]) 25 list([54, 176, 51])] 26 [list([168, 116, 18]) list([94, 81, 49]) list([192, 41, 45]) 27 list([137, 182, 178])]] 28 29 [[list([31, 68, 194]) list([174, 1, 104]) list([236, 63, 160]) 30 list([19, 20, 44])] 31 [list([238, 60, 184]) list([172, 106, 34]) list([121, 173, 227]) 32 list([198, 145, 202])] 33 [list([183, 225, 163]) list([93, 101, 74]) list([166, 39, 45]) 34 list([69, 169, 247])] 35 [list([195, 47, 140]) list([205, 195, 218]) list([142, 240, 180]) 36 list([230, 50, 121])]] 37 38 [[list([174, 5, 140]) list([157, 144, 74]) list([206, 86, 223]) 39 list([121, 40, 95])] 40 [list([158, 68, 102]) list([3, 42, 87]) list([61, 76, 57]) 41 list([2, 77, 103])] 42 [list([216, 241, 127]) list([175, 45, 225]) list([11, 153, 174]) 43 list([199, 98, 154])] 44 [list([192, 174, 217]) list([12, 36, 70]) list([72, 164, 22]) 45 list([18, 121, 128])]]]

次にcoordinateを作ります。

python

1>>> coordinate = np.zeros(N*N, dtype=object) 2>>> for i in range(N*N): 3... coordinate[i] = [random.randint(0,N-1) for i in range(3)] 4... 5>>> coordinate = coordinate.reshape(N,N) 6>>> print(coordinate) 7[[list([1, 1, 1]) list([2, 0, 0]) list([0, 2, 3]) list([0, 2, 1])] 8 [list([1, 1, 3]) list([2, 1, 2]) list([3, 3, 3]) list([0, 3, 2])] 9 [list([0, 0, 1]) list([0, 0, 1]) list([1, 0, 3]) list([1, 2, 0])] 10 [list([0, 1, 3]) list([0, 0, 1]) list([2, 3, 2]) list([1, 3, 2])]]

最後にimgAryを生成します。

python

1>>> coordinate_a = np.array(list(coordinate.reshape(-1))).reshape(N,N,3) 2>>> coordinate_s = (coordinate_a[:,:,0]*(N*N)+coordinate_a[:,:,1]*N +coordinate_a[:,:,2]).reshape(-1) 3>>> imgAry = voxel.reshape(-1)[coordinate_s].reshape(N, N) 4>>> print(imgAry) 5[[list([9, 69, 173]) list([31, 68, 194]) list([88, 82, 84]) 6 list([131, 62, 104])] 7 [list([223, 159, 43]) list([121, 173, 227]) list([18, 121, 128]) 8 list([158, 98, 121])] 9 [list([220, 1, 186]) list([220, 1, 186]) list([240, 192, 199]) 10 list([42, 92, 125])] 11 [list([133, 123, 114]) list([220, 1, 186]) list([142, 240, 180]) 12 list([192, 41, 45])]]

このやり方は、fuji_sanさんの方法よりはかなり速いと思います。
これ以上高速にしたければ、リストのndarrayではなく、高次元のndarrayを使うのが良いのですが、元データの作成や、imgAryの使い方によるところもあるので、なんとも言えないですね。

投稿2021/03/10 09:20

ppaul

総合スコア24666

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuji_san

2021/03/13 07:57 編集

ご回答ありがとうございます。 ご提示の方法をColaboratoryで試してみましたが速度が2倍遅くなりました。実際に必要としているN=512ではご教授頂いた方法では難しいようです。 以下、試したコードです。ボクセル値はRGBではなくGrey値なので一部コードを改変しています。 ```python import numpy as np import random N = 512 voxel = np.zeros(N*N*N, dtype=object) for i in range(N*N*N): voxel[i] = random.randint(0,255) voxel = voxel.reshape(N,N,N) coordinate = np.zeros(N*N, dtype=object) for i in range(N*N): coordinate[i] = [random.randint(0,N-1) for i in range(3)] def test1(): coordinate = coordinate.reshape(N,N) coordinate_a = np.array( list(coordinate.reshape(-1))).reshape(N,N,3) coordinate_s = (coordinate_a[:, :, 0]*(N*N) + coordinate_a[:, :, 1]*N + coordinate_a[:,:,2]).reshape(-1) imgAry = voxel.reshape(-1)[coordinate_s].reshape(N, N) def test2(): imgAry = np.array( [voxel[ j[0], j[1], j[2] ] for j in coordinate] ).reshape(N,N) %timeit -n 1 test1() %timeit -n 1 test2() ''' 1 loop, best of 5: 496 ms per loop 1 loop, best of 5: 233 ms per loop ''' ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問