2016-05-22 3 views
0

形状の配列Xが必要です(n_samples、n_cols、n_rows、n_channels)。 ValueError:順序で配列要素を設定する私はNumpyで各チャンネルの画像リストを配列にロードするにはどうすればいいですか?

import glob 
from skimage import io, color 
import numpy as np 

def loadfunc(files) 
    for fl in files: 
     img = color.rgb2lab(io.imread(fl)) 
     L = img[:,:,:1] 
     ab = img[:,:,1:] 
     yield L,ab 

X,y = np.fromiter(loadfunc(glob.glob('path/to/images/*.png')),float) 

を試してみましたし、私はこのエラーを取得する形状(n_標本、n_cols、n_rows、n_channels)

と配列yをしたいです。

これは幾分一般的な操作である必要があります。誰かがnumpyの配列に画像データをロードしたい場合は、何かが欠けているはずですか?

+1

申し訳ありませんが、インポートステートメントを追加しました – BigBoy1337

+0

['np.fromiter'](http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.fromiter.html)は、配列の要素* 1つの配列*だからあなたのコードは実際に2要素のタプルの配列を作ることを試みています....私はあなたが現在しようとしていることをする方法を見つけようとしています... –

+0

'X'に' L'配列、 'y'は' ab'配列ですか? – unutbu

答えて

1

np.fromiterへのイテレータを使用すると、DTYPEを述べることが必要です。 dtype=floatを使用する場合、iterableの各値はfloatでなければなりません。もし、

def loadfunc(files): 
    for fl in files: 
     img = skcolor.rgb2lab(skio.imread(fl)[..., :3]) 
     yield img 

arrs = loadfunc(files) 
Z = np.fromiter(IT.chain.from_iterable([arr.flat for arr in arrs]), dtype=float) 

np.fromiterので戻り1Dアレイ:あなたがloadfuncから単numpyの配列を得た場合は、itertools.chain.from_iterableと連結し、次いでnp.fromiterに渡すことができる平坦化配列の値を超えるイテレータを取得するために彼らのflat属性を使用することができ

Z = Z.reshape(len(files), h, w, n) 

これは、同じ形状の各画像に依存していることに注意してください。 は最後に、yXL値とab値をロードします

X = Z[..., :1] 
y = Z[..., 1:] 

import glob 
import itertools as IT 
import numpy as np 
import skimage.io as skio 
import skimage.color as skcolor 

def loadfunc(files): 
    for fl in files: 
     img = skcolor.rgb2lab(skio.imread(fl)[..., :3]) 
     yield img 

files = glob.glob('path/to/images/*.png') 
arrs = loadfunc(files) 
first = next(arrs) 
h, w, n = first.shape 

Z = np.fromiter(IT.chain.from_iterable(
    [first.flat] + [arr.flat for arr in arrs]), dtype=float) 
Z = Z.reshape(len(files), h, w, n) 
X = Z[..., :1] 
y = Z[..., 1:] 

についてquestion in the comments:私はロードを分離することを信じている

If I wanted to do extra processing to L and ab, where would I do that?

〜からデータの処理。 2つの機能を区別することによって、異なるソースからの異なるデータを同じ処理機能に渡す可能性を残します。データの読み込みと処理(ab値のKNN分類など)をloadfuncに入れると、ファイルからデータをロードせずにKNN分類コードを再利用する方法はありません。


あなたは私たちが (n_cols, n_rows, n_channels, n_samples)(n_samples, n_cols, n_rows, n_channels)からの軸の順序を変更できるようにする場合は、 、コードがnp.stackを使用して簡単にすることができます。

import glob 
import numpy as np 
import skimage.io as skio 
import skimage.color as skcolor 

def loadfunc(files): 
    for fl in files: 
     img = skcolor.rgb2lab(skio.imread(fl)[..., :3]) 
     yield img 

files = glob.glob('path/to/images/*.png') 
Z = np.stack(loadfunc(files), axis=-1) 
X = Z[..., :1, :] 
Y = Z[..., 1:, :] 

このコードは簡単で、することが好ましいです上記のコード(np.fromiterを使用)。

+1

私がLとabに余分な処理をしたいのであれば、どこでそれを行うのですか?たとえば、私はab値のKNN分類を実行したいと思います。計算上、あなたが示唆したことを実行してからYを引き離し、分類から追加の配列を形成する方が理にかなっていますか?それとも、Yが作成される前にそれをするのが理にかなっていますか?もし私がこれをやりたいのであれば、@ Tadhg McDonald-Jensenのようなものはどこにあるのでしょうか? – BigBoy1337

+0

私は上記のコメントが[このコメント]を参照していたと仮定します(http://stackoverflow.com/questions/37379696/how-do-i-load-a-list-of-images-into-an-array-for-私のブラウザで実際に_above_ここにある各チャネルの中でnumpy/37379875?noredirect = 1#comment62270895_37379875) –

+0

@ BigBoy1337:データの処理と読み込みを分けることが望ましいと思います。なぜ、上記の理由を説明する単語を追加します。 – unutbu

1

numpy.fromiter同時アレイの作成をサポートし、そこnpでこれを行う方法があるが、私の知る限り、あなたが分割する必要があるかもしれません(X,yにアンパックされる)ことが可能であり、タプルとしてそれらを返しません。代わりにtee

# the built in map in python 3 uses iteration, 
# uncomment the added imap import if you are using python 2 
from itertools import tee #, imap as map 

from operator import itemgetter 

iter_a, iter_b = tee(loadfunc(glob.glob('path/to/images/*.png'))) 

X = np.fromiter(map(itemgetter(0),iter_a), float) #array from the first elements 
y = np.fromiter(map(itemgetter(1),iter_b), float) #array from the second elements 
+0

hmmだから、loadfuncはまだ私の質問にある関数のように各繰り返しでXとyを返すでしょうか? – BigBoy1337

+0

はい、私は 'loadfunc'が実際にもっと大きく/複雑になるかもしれないという前提を作り出していましたので、書き直す必要のない編集を提案しました。' loadfunc'を再作成して、追加の議論でそしてそれを2回呼ぶ。 –

+0

これはうまく実行できますか?これを試してみると、私はまだこれを取得しています:ValueError:シーケンスで配列要素を設定する。 XとYを設定する最後の2行にあると信じています – BigBoy1337

0

通常、繰り返しで配列を作成するときには、値をリストに集めてその配列を作成します。または空のリストを割り当てて値をスロットに割り当てます。ここ

は、発電機は、アレイのタプルを返す割り当てを、行うための方法だ:

def mk_array(N): 
    for i in range(N): 
     img=np.ones((2,3,3),int) 
     L=img[:,:,:1]*i 
     ab=img[:,:,1:].astype(float)*i/10 
     yield L,ab 

Iは、int型の配列、浮動小数点数の他の配列を作りました。それは、それらを1つに結びつける誘惑を減らす。

In [157]: g=mk_array(4) 

In [158]: for i,v in enumerate(g): 
    print(v[0].shape,v[1].shape) 
    .....:  
(2, 3, 1) (2, 3, 2) 
(2, 3, 1) (2, 3, 2) 
(2, 3, 1) (2, 3, 2) 
(2, 3, 1) (2, 3, 2) 

正しい形状のターゲット配列を割り当てます。ここで私は第三軸繰返しを置くが、それはどこでも

In [159]: L, ab = np.empty((2,3,4,1),int), np.empty((2,3,4,2),float) 

In [160]: for i,v in enumerate(g): 
    L[...,i,:], ab[...,i,:] = v 

私の推測可能性があり、これは任意のfromiterstack代替と同じくらい速いです。そして、ファイルから読み込むことによってコンポーネントが生成されると、そのステップは最もコストがかかるものになります。反復メカニズムや配列のコピーよりも多くのことが行われます。

================

イテレータがスカラーのタプルを返した場合、我々はfromiterを使用することができます。

def mk_array1(N): 
    for i in range(N): 
     img=np.ones((2,3,3),int) 
     L=img[:,:,:1]*i 
     ab=img[:,:,1:].astype(float)*i/10 
     for i,j in zip(L.ravel(),ab.ravel()): 
      yield i,j 

In [184]: g=mk_array1(2) 

In [185]: V=np.fromiter(g,dtype=('i,f')) 

1dの構造化された配列を生成します

In [187]: V['f0'] 
Out[187]: array([0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], dtype=int32) 

In [188]: V.reshape(2,2,3)['f0'] 
Out[188]: 
array([[[0, 0, 0], 
     [0, 0, 0]], 

     [[1, 1, 1], 
     [1, 1, 1]]], dtype=int32) 

In [189]: V.reshape(2,2,3)['f1'] 
Out[189]: 
array([[[ 0. , 0. , 0. ], 
     [ 0. , 0. , 0. ]], 

     [[ 0.1, 0.1, 0.1], 
     [ 0.1, 0.1, 0.1]]], dtype=float32) 
:再形成、およびアレイは、フィールド名によって分離することができる

In [186]: V 
Out[186]: 
array([(0, 0.0), (0, 0.0), (0, 0.0), (0, 0.0), (0, 0.0), (0, 0.0), 
     (1, 0.10000000149011612), (1, 0.10000000149011612), 
     (1, 0.10000000149011612), (1, 0.10000000149011612), 
     (1, 0.10000000149011612), (1, 0.10000000149011612)], 
     dtype=[('f0', '<i4'), ('f1', '<f4')]) 

In [200]: dt=np.dtype([('f0',int,(2,3,1)),('f1',float,(2,3,2))]) 

In [201]: g=mk_array(2) # the original generator 

In [202]: V=np.fromiter(g,dtype=dt) 

In [203]: V['f0'] 
Out[203]: 
array([[[[0], 
     [0], 
     [0]], 
     .... 

     [[1], 
     [1], 
     [1]]]]) 

In [204]: _.shape 
Out[204]: (2, 2, 3, 1) 

のこの使用を:私はより複雑dtype、各フィールドはアレイを有するものを定義する場合、どのよう

================

fromiterの化合物dtypeもhttps://stackoverflow.com/a/12473478/901925

に記載されています。これは実際にタプルのリストから構造化された配列を構築する通常の方法のバリエーションです。私たちは2つのアレイを作成する二つの方法の時間をすることができ要するに

np.array([tuple(x) for x in something], dtype=dt) 

Nの広い範囲のために

def foo1(N): 
    g = mk_array(N)          
    L, ab = np.empty((N,2,3,1),int), np.empty((N,2,3,2),float) 
    for i,v in enumerate(g): 
     L[i,...], ab[i,...] = v 
    return L, ab 

def foo2(N): 
    dt=np.dtype([('f0',int,(2,3,1)),('f1',float,(2,3,2))]) 
    g = mk_array(N) 
    V=np.fromiter(g, dtype=dt) 
    return V['f0'], V['f1'] 

これら2つの機能はほぼ同じ時間がかかり、私が式を使用しまし回以上。私はfoo1の利点を開始する前に1秒にランタイムをプッシュする必要があります。

関連する問題