2016-05-03 7 views
1

Warum die folgenden Werke:python col Namen in den np.array

mat = np.array(
    [(0,0,0), 
    (0,0,0), 
    (0,0,0)], 
    dtype=[('MSFT','float'),('CSCO','float'),('GOOG','float') ] 
    ) 

während dies nicht:

mat = np.array(
    [[0]*3]*3, 
    dtype=[('MSFT','float'),('CSCO','float'),('GOOG','float')] 
    ) 

Wie kann ich eine Matrix leicht wie

erstellen

[[None]*M]*N

Aber mit Tupeln in der Lage sein, Namen zu Spalten zuweisen?

Antwort

3

Wenn Sie eine Reihe von 1D-Arrays (Spalten) haben würden Sie zusammenführen möchten, während die Spaltennamen zu halten, können Sie np.rec.fromarrays verwenden:

>>> dt = np.dtype([('a', float),('b', float),('c', float),]) 
>>> np.rec.fromarrays([[0] * 3 ] * 3, dtype=dt) 
rec.array([(0.0, 0.0, 0.0), (0.0, 0.0, 0.0), (0.0, 0.0, 0.0)], dtype=[('a', '<f8'), ('b', '<f8'), ('c', '<f8')]) 

Dies gibt Ihnen eine Aufzeichnung/strukturierte Anordnung, bei der Spalten können Namen & verschiedene Datentypen.

+0

Es ist interessant, dass 'rec.fromarrays' die Kopie-durch-Felder-Methode des Füllens des strukturierten Arrays verwendet. – hpaulj

4

Wenn ich mache einen Null-Array mit Ihrem dtype

In [548]: dt=np.dtype([('MSFT','float'),('CSCO','float'),('GOOG','float') ]) 

In [549]: A = np.zeros(3, dtype=dt) 

In [550]: A 
Out[550]: 
array([(0.0, 0.0, 0.0), (0.0, 0.0, 0.0), (0.0, 0.0, 0.0)], 
     dtype=[('MSFT', '<f8'), ('CSCO', '<f8'), ('GOOG', '<f8')]) 

Hinweis, dass die Anzeige eine Liste von Tupeln zeigt. Das ist beabsichtigt, um die dtype Datensätze aus einer Zeile eines 2d (gewöhnlichen) Arrays zu unterscheiden.

Das bedeutet auch, dass Sie beim Erstellen des Arrays oder beim Zuweisen von Werten auch eine Liste von Tupeln verwenden müssen.

Zum Beispiel wollen wir eine Liste der Liste:

In [554]: ll = np.arange(9).reshape(3,3).tolist() 
In [555]: ll 

In [556]: A[:]=ll 
... 
TypeError: a bytes-like object is required, not 'list' 

aber wenn ich es in eine Liste von Tupeln drehen:

In [557]: llt = [tuple(i) for i in ll] 

In [558]: llt 
Out[558]: [(0, 1, 2), (3, 4, 5), (6, 7, 8)] 

In [559]: A[:]=llt 

In [560]: A 
Out[560]: 
array([(0.0, 1.0, 2.0), (3.0, 4.0, 5.0), (6.0, 7.0, 8.0)], 
     dtype=[('MSFT', '<f8'), ('CSCO', '<f8'), ('GOOG', '<f8')]) 

Zuordnung funktioniert gut. Diese Liste kann auch direkt in array verwendet werden.

In [561]: np.array(llt, dtype=dt) 
Out[561]: 
array([(0.0, 1.0, 2.0), (3.0, 4.0, 5.0), (6.0, 7.0, 8.0)], 
     dtype=[('MSFT', '<f8'), ('CSCO', '<f8'), ('GOOG', '<f8')]) 

Auf ähnliche Werte zuweisen einen Datensatz erfordert ein Tupel, keine Liste:

In [563]: A[0]=(10,12,14) 

Die andere übliche Art und Weise Werte der Einstellung auf einem Feld für Feld Basis. Das kann mit einer Liste oder Array erfolgen:

In [564]: A['MSFT']=[100,200,300] 

In [565]: A 
Out[565]: 
array([(100.0, 12.0, 14.0), (200.0, 4.0, 5.0), (300.0, 7.0, 8.0)], 
     dtype=[('MSFT', '<f8'), ('CSCO', '<f8'), ('GOOG', '<f8')]) 

Die np.rec.fromarrays Methode in der anderen Antwort empfohlen endet mit der Kopie-by-Felder nähern. Es ist Code ist, im Wesentlichen:

+1

Dies kommt ziemlich oft vor, gibt es einen Grund, dass der Fall einer Liste von Listen nicht als eine akzeptable Eingabe anstelle einer Liste von Tupeln angesehen wurde? Ich habe noch keine endgültige Begründung dafür gefunden. –

+1

Es scheint mir logisch, dass die Eingabesyntax den Anzeigestil widerspiegelt. Aber ich habe das Thema auf GitHub-Problemen oder dem Entwicklerforum nicht untersucht. So fehlt Anfängern häufig die Unterscheidung zwischen dtype Feldern und 2d Spalten, besonders wenn sie einen csv laden. Someelse hat gerade gefragt, warum sie kein strukturiertes und ein flaches Array hinzufügen könnten. – hpaulj

+0

Ich könnte mir ein Argument vorstellen, das von der Tatsache herrührt, dass ein "dtype" -Eintrag als eine 2-Feld-Sequenz definiert und somit als unveränderlich festgelegt ist. – mtzl

Verwandte Themen