2017-03-02 4 views
1

Ich kam in dieser Codezeile, die numpy verwendet:Python - numpy umformen

img = data.reshape(data.shape[0], 3, 32, 32) 

Ich verstand diese Codezeile, mit Ausnahme von data.shape[0]. Was ich weiß ist, dass dieser Teil die Anzahl der Zeilen zurückgibt. Aber was ich nicht erhalten habe ist, wie die data (d. H. Zeilen) zu einer 32x32 Matrix mit 3-channels umgeformt werden. Warum wurde data nicht alleine verwendet?

Vielleicht verwirre ich die Dinge hier?

Danke.

+0

Das erneute Lesen der Dokumente kann hilfreich sein. – Divakar

+0

Was ist die Form von 'Daten'? Es muss mindestens 2d sein, und das 'data.shape [1:]' Werte haben das gleiche Produkt wie 3 * 32 * 32. – hpaulj

Antwort

1

Eine Möglichkeit, die dies sinnvoll wäre, wäre, wenn Sie genau wissen, wie die letzten, aber viele Dimensionen organisiert sind, aber Sie nicht genau wissen, wie viele Zeilen es gibt; zum Beispiel

In [9]: data.shape 
Out[9]: (5, 3072) 

In [7]: img = data.reshape(data.shape[0], 3, 32, 32) # 3072 = 3*32*32 

In [10]: img.shape 
Out[10]: (5, 3, 32, 32) 
2

Beim Umformen einer Matrix sollte die neue Form mit der ursprünglichen Form kompatibel sein.

Um dies dynamisch sicherzustellen, verwendet dieser Code data.shape [0], um die Anzahl der Zeilen der ursprünglichen Matrix zu erhalten (d. H. Die erste Dimension von data). Wenn dies bekannt ist, formt es die Matrix in eine 4-d-Matrix um, die wie folgt definiert ist: Zeilen | 3 | 32 | 32.

Da Sie darauf hingewiesen haben, dass das Array selbst verwendet werden könnte, überprüft dieser Code nicht die Anzahl der Zeilen, sondern die Anzahl der Zeilen, um sicherzustellen, dass die Zeilenelemente nicht in die neuen Spalten verschoben werden während der Umformung.

1

Nehmen wir an, Sie haben ein Array mit N Zeilen, wobei jede Zeile ein 3 * 32 * 32 = 3072 langes Array ist. Wenn Sie nicht sicher wissen, wie viele Zeilen es gibt, aber Sie möchten, dass der Rest auf (3, 32, 32) umgestaltet wird, können Sie die angezeigte Zeile verwenden.

Andernfalls würden Sie eine Fehlermeldung erhalten:

>>> import numpy as np 
>>> n_lines = 10 
>>> data = np.arange(n_lines*3*32*32) 
>>> data.reshape(n_lines + 1 , 3*32*32) # notice the + 1 !! 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: total size of new array must be unchanged 

Aber wenn Sie die richtige Nummer verwenden:

>>> data.reshape(n_lines, 3*32*32) 
array([[ 0,  1,  2, ..., 3069, 3070, 3071], 
     [ 3072, 3073, 3074, ..., 6141, 6142, 6143], 
     [ 6144, 6145, 6146, ..., 9213, 9214, 9215], 
     ..., 
     [21504, 21505, 21506, ..., 24573, 24574, 24575], 
     [24576, 24577, 24578, ..., 27645, 27646, 27647], 
     [27648, 27649, 27650, ..., 30717, 30718, 30719]]) 
>>> data.reshape(n_lines, 3, 32, 32) 
array([[[[ 0,  1,  2, ..., 29, 30, 31], 
     [ 32, 33, 34, ..., 61, 62, 63], 
     [ 64, 65, 66, ..., 93, 94, 95], 
     ..., 
     [ 928, 929, 930, ..., 957, 958, 959], 
     [ 960, 961, 962, ..., 989, 990, 991], 
     [ 992, 993, 994, ..., 1021, 1022, 1023]], 

     [[ 1024, 1025, 1026, ..., 
1

umformen kann nicht die Größe der Daten ändern, aber es kann die Anzahl der Dimensionen ändern. Wenn die ursprüngliche Form z.B. (10x3072) oder (10x3x1024) können Sie das komplette Array zu 10x3x32x32 aber nicht zu 9x3x32x32 umformen.

Anscheinend wird dieser Code geschrieben, um die erste Dimension unverändert zu lassen und den Rest des Arrays umzuformen. Unabhängig von der tatsächlichen Form von data ist img immer Nx3x32x32, wenn die Größe data N * 3072 ist. Andernfalls wird ein Fehler ausgegeben.

Wahrscheinlich wer den Code schrieb wusste nicht, dass Sie -1 zu reshape, um automatisch die Größe einer Dimension passieren kann:

img = data.reshape(-1, 3, 32, 32) 

Dies ist möglich, weil die Gesamtgröße der Daten muss unverändert bleiben .

Why didn't data alone be used?

Schwer zu sagen, ohne die frühere Form der Daten zu kennen, aber aus dem Namen img Ich würde abziehen, dass die neu geformte Array wahrscheinlich eine Sammlung von n 32x32 RGB-Bildern halten soll.