2016-08-09 56 views
4

Ich habe ein Problem mit np.append.ValueError: alle Eingabe-Arrays müssen die gleiche Anzahl von Dimensionen haben

Ich versuche, die letzte Spalte von 20x361 Matrix n_list_converted mithilfe des unten stehenden Codes zu duplizieren:

n_last = [] 
n_last = n_list_converted[:, -1] 
n_lists = np.append(n_list_converted, n_last, axis=1) 

Aber ich bekomme Fehler:

ValueError: all the input arrays must have same number of dimensions

Allerdings habe ich die Matrix geprüft Dimensionen von

print(n_last.shape, type(n_last), n_list_converted.shape, type(n_list_converted)) 

tun und ich

(20L,) (20L, 361L)

so die Abmessungen übereinstimmen? Wo ist der Fehler?

+5

Versuchen Sie 'np.column_stack'. – Divakar

+2

Es hat funktioniert! Aber warum? – odo22

Antwort

5

wenn ich mit einer 3x4-Array zu starten, und eine 3x1-Array verketten, mit der Achse 1, erhalte I einen 3x5-Array:

In [911]: x = np.arange(12).reshape(3,4) 
In [912]: np.concatenate([x,x[:,-1:]], axis=1) 
Out[912]: 
array([[ 0, 1, 2, 3, 3], 
     [ 4, 5, 6, 7, 7], 
     [ 8, 9, 10, 11, 11]]) 
In [913]: x.shape,x[:,-1:].shape 
Out[913]: ((3, 4), (3, 1)) 

beachte, dass beiden Eingänge 2 Dimensionen verketten.

Auslassen der : und x[:,-1] (3,) Form - es 1d ist, und damit die Fehler:

In [914]: np.concatenate([x,x[:,-1]], axis=1) 
... 
ValueError: all the input arrays must have same number of dimensions 

Der Code für np.append ist (in diesem Fall, wo Achse angegeben)

return concatenate((arr, values), axis=axis) 

Also mit einer leichten Änderung der Syntax append funktioniert. Statt einer Liste benötigt es 2 Argumente. Es imitiert die Liste append ist Syntax, sollte aber nicht mit dieser Listenmethode verwechselt werden.

In [916]: np.append(x, x[:,-1:], axis=1) 
Out[916]: 
array([[ 0, 1, 2, 3, 3], 
     [ 4, 5, 6, 7, 7], 
     [ 8, 9, 10, 11, 11]]) 

np.hstack zuerst stellt sicher, dass alle Eingänge sind atleast_1d und dann verketten hat:

return np.concatenate([np.atleast_1d(a) for a in arrs], 1) 

So erfordert es die gleiche x[:,-1:] Eingang. Im Wesentlichen die gleiche Aktion.

np.column_stack macht auch ein Verketten auf der Achse 1. Aber zuerst leitet es 1d Eingänge durch

array(arr, copy=False, subok=True, ndmin=2).T 

Dies ist eine allgemeine Art und Weise ist die Dreh (3) in eine Matrix (3,1) Array.

In [922]: np.array(x[:,-1], copy=False, subok=True, ndmin=2).T 
Out[922]: 
array([[ 3], 
     [ 7], 
     [11]]) 
In [923]: np.column_stack([x,x[:,-1]]) 
Out[923]: 
array([[ 0, 1, 2, 3, 3], 
     [ 4, 5, 6, 7, 7], 
     [ 8, 9, 10, 11, 11]]) 

Alle diese ‚Stacks‘ kann bequem sein, aber auf lange Sicht ist es wichtig, Dimensionen zu verstehen und die Basis np.concatenate. Außerdem wissen Sie, wie Sie den Code für Funktionen wie diesen nachschlagen. Ich benutze die ipython?? Magie sehr.

Und in Zeittests ist die np.concatenate merklich schneller - mit einem kleinen Array wie diesem macht die zusätzliche Schichten von Funktionsaufrufen einen großen Zeitunterschied.

3

(n,) und (n, 1) haben nicht die gleiche Form. Versuchen Sie, den Vektor zu einem Array Gießen durch die [:, None] Notation:

n_lists = np.append(n_list_converted, n_last[:, None], axis=1) 

Alternativ kann, wenn n_last Extrahieren Sie

n_last = n_list_converted[:, -1:] 

zu bekommen eine (20, 1) Array verwenden können.

2

Der Grund, warum Sie Ihren Fehler erhalten, ist, weil eine "1 von n" -Matrix von einem Array der Länge n unterscheidet.

Ich empfehle stattdessen hstack() und vstack() statt. So:

import numpy as np 
a = np.arange(32).reshape(4,8) # 4 rows 8 columns matrix. 
b = a[:,-1:]     # last column of that matrix. 

result = np.hstack((a,b))  # stack them horizontally like this: 
#array([[ 0, 1, 2, 3, 4, 5, 6, 7, 7], 
#  [ 8, 9, 10, 11, 12, 13, 14, 15, 15], 
#  [16, 17, 18, 19, 20, 21, 22, 23, 23], 
#  [24, 25, 26, 27, 28, 29, 30, 31, 31]]) 

Beachten Sie die wiederholte "7, 15, 23, 31" Spalte. Beachten Sie auch, dass ich a[:,-1:] anstelle von a[:,-1] verwendet habe. Meine Version erzeugt eine Spalte:

array([[7], 
     [15], 
     [23], 
     [31]]) 

Anstatt eine Reihe array([7,15,23,31])


Edit: append() ist viel langsamer. Lesen Sie this answer.

+0

'np.append' ist langsamer als die Liste' .append'; aber vergleichbar mit den 'Stacks'. Es verwendet 'np.concatenate'. – hpaulj

+0

@hpaulj So ... Wie ich sagte mit 'append' vs' stack' ist das gleiche mit 2 Matrizen und 'stack' ist besser für mehr als 2 Elemente, so' stack' ist immer _wenigstens so gut wie_' anhängen '. – RuRo