2014-06-25 5 views
7

Ich möchte ein numpy Array von einem iterablen erstellen, die Tupel von Werten wie eine Datenbankabfrage ergibt.Wie erstellen Sie ein mehrdimensionales numpy Array aus einem iterierbaren Tupel?

Wie so:

data = db.execute('SELECT col1, col2, col3, col4 FROM data') 
A = np.array(list(data)) 

Gibt es eine Möglichkeit schneller Weg, dies zu tun, ohne die iterable erste in eine Liste zu konvertieren?

+0

nicht sicher, ob dies funktioniert: http://docs.scipy.org/doc/numpy/reference/generated/numpy.fromiter.html – Fabricator

+1

@Fabricator Die Dokumentation sagt, dass es ein * 1d * Array aus dem iterablen erstellt. In diesem Fall würde ein Array von Objekten anstelle eines 2d-Arrays mit 4 Spalten erstellt. – Bakuriu

+0

'np.loadtxt' ist ein Beispiel für das Erstellen eines Arrays aus einem iterablen, nämlich einer Datei. Vereinfacht ausgedrückt liest es eine Zeile, erstellt eine Liste aus seinen Teilzeichenfolgen und hängt sie an eine Liste an. Am Ende konvertiert es die Liste der Listen in ein Array. – hpaulj

Antwort

1

Obwohl technisch nicht eine Antwort auf meine Frage, fand ich einen Weg zu tun, was ich zu tun versucht:

def get_cols(db, cols): 
    def get_col(col): 
     data = db.execute('SELECT '+col+' FROM data', dtype=np.float64) 
     return np.fromiter((v[0] for v in data)) 

    return np.vstack([get_col(col) for col in cols]).T 
+0

Ist das schneller? – hpaulj

1

Ich bin kein erfahrener Benutzer von numpy, aber hier ist eine mögliche Lösung für die allgemeine Frage:

>>> i = iter([(1, 11), (2, 22)]) 
>>> i 
<listiterator at 0x5b2de30>     # a sample iterable of tuples 
>>> rec_array = np.fromiter(i, dtype='i4,i4') # mind the dtype 
>>> rec_array         # rec_array is a record array 
array([(1, 11), (2, 22)], 
    dtype=[('f0', '<i4'), ('f1', '<i4')]) 
>>> rec_array['f0'], rec_array[0]    # each field has a default name 
(array([1, 2]), (1, 11)) 
>>> a = rec_array.view(np.int32).reshape(-1,2) # let's create a view 
>>> a 
array([[ 1, 11], 
     [ 2, 22]]) 
>>> rec_array[0][1] = 23 
>>> a           # a is a view, not a copy! 
array([[ 1, 23], 
     [ 2, 22]]) 

ich gehe davon aus, dass alle Spalten des gleichen Typs sind, sonst rec_array ist schon was Sie wollen.

In Ihrem Fall verstehe ich nicht ganz, was db in Ihrem Beispiel ist. Wenn es ein Cursor-Objekt ist, dann können Sie einfach seine Methode aufrufen und eine Liste von Tupeln erhalten. In den meisten Fällen möchte die Datenbankbibliothek kein teilweise gelesenes Abfrageergebnis behalten und wartet auf den Code, der jede Zeile verarbeitet, dh in dem Moment, wenn die execute Methode zurückkehrt, sind alle Daten bereits in einer Liste gespeichert, und es gibt kaum ein Problem der Verwendung von anstelle von cursor Instanz zu iterieren.

Verwandte Themen