tldr: NumPy scheint, wenn numerische Berechnungen auf numerischen Arrays durchgeführt werden. Obwohl es möglich ist (siehe unten), ist NumPy dafür nicht gut geeignet. Sie sind wahrscheinlich besser dran mit Pandas.
Die Ursache des Problems:
Die Werte als Strings sortiert werden. Sie müssen sie als ints
sortieren.
Dies passierte, weil order_array
Strings enthält. Sie müssen diese Zeichenfolgen gegebenenfalls in ints
konvertieren.
Das Konvertieren von Dtypes von String-dtype in numerisch dtype erfordert die Zuweisung von Speicherplatz für ein neues Array. Daher wäre es wahrscheinlich besser, die Art, wie Sie order_array
von Anfang an erstellen, zu überarbeiten.
Interessanterweise, obwohl Sie die Werte ints umgewandelt, wenn Sie
order_array = np.array(rows_list)
NumPy standardmäßig Aufruf erzeugt ein homogenes Array. In einem homogenen Array hat jeder Wert den gleichen dtype. Also versuchte NumPy, den gemeinsamen Nenner unter all Ihren Werten zu finden und wählte einen String dtype, der den Aufwand, den Sie in die Umwandlung der Strings in Ints setzen, vereitelt!
Sie können die dtype für sich selbst überprüfen, indem order_array.dtype
Inspektion:
In [42]: order_array = np.array(rows_list)
In [43]: order_array.dtype
Out[43]: dtype('|S4')
Nun, wie beheben wir das?
ein Objekt dtype Verwendung:
Der einfachste Weg ist es, ein 'Objekt' dtype
In [53]: order_array = np.array(rows_list, dtype='object')
In [54]: order_array
Out[54]:
array([[2008, 1, 23, AAPL, Buy, 100],
[2008, 1, 30, AAPL, Sell, 100],
[2008, 1, 23, GOOG, Buy, 100],
[2008, 1, 30, GOOG, Sell, 100],
[2008, 9, 8, GOOG, Buy, 100],
[2008, 9, 15, GOOG, Sell, 100],
[2008, 5, 1, XOM, Buy, 100],
[2008, 5, 8, XOM, Sell, 100]], dtype=object)
Das Problem hier zu verwenden ist, dass np.lexsort
oder np.sort
funktionieren nicht auf Anordnungen von dtype object
. Um das zu umgehen dieses Problem, könnte man die rows_list
sortieren, bevor die Schaffung order_list
:
In [59]: import operator
In [60]: rows_list.sort(key=operator.itemgetter(0,1,2))
Out[60]:
[(2008, 1, 23, 'AAPL', 'Buy', 100),
(2008, 1, 23, 'GOOG', 'Buy', 100),
(2008, 1, 30, 'AAPL', 'Sell', 100),
(2008, 1, 30, 'GOOG', 'Sell', 100),
(2008, 5, 1, 'XOM', 'Buy', 100),
(2008, 5, 8, 'XOM', 'Sell', 100),
(2008, 9, 8, 'GOOG', 'Buy', 100),
(2008, 9, 15, 'GOOG', 'Sell', 100)]
order_array = np.array(rows_list, dtype='object')
Eine bessere Möglichkeit wäre, die ersten drei Spalten in datetime.date Objekte zu kombinieren:
import operator
import datetime as DT
for i in ...:
seq = [DT.date(int(x.year), int(x.month), int(x.day)) ,s_sym, 'Buy', 100]
rows_list.append(seq)
rows_list.sort(key=operator.itemgetter(0,1,2))
order_array = np.array(rows_list, dtype='object')
In [72]: order_array
Out[72]:
array([[2008-01-23, AAPL, Buy, 100],
[2008-01-30, AAPL, Sell, 100],
[2008-01-23, GOOG, Buy, 100],
[2008-01-30, GOOG, Sell, 100],
[2008-09-08, GOOG, Buy, 100],
[2008-09-15, GOOG, Sell, 100],
[2008-05-01, XOM, Buy, 100],
[2008-05-08, XOM, Sell, 100]], dtype=object)
Auch wenn diese ist einfach, ich mag keine NumPy Arrays von dtype Objekt. Sie erhalten weder die Geschwindigkeit noch die Speicherplatzersparnis von NumPy-Arrays mit nativen dtypes. An dieser Stelle könnte es sein, dass Sie mit einer Python-Liste von Listen schneller und syntaktisch leichter umgehen können.
ein strukturiertes Array:
Eine NumPy-Ish-Lösung, die nach wie vor Vorteile Geschwindigkeit und Speicher bietet, ist eine structured array zu verwenden (im Gegensatz zu homogenen Array). Um ein strukturierten Array zu machen mit np.array
Sie benötigen eine dtype explizit liefern:
dt = [('year', '<i4'), ('month', '<i4'), ('day', '<i4'), ('symbol', '|S8'),
('action', '|S4'), ('value', '<i4')]
order_array = np.array(rows_list, dtype=dt)
In [47]: order_array.dtype
Out[47]: dtype([('year', '<i4'), ('month', '<i4'), ('day', '<i4'), ('symbol', '|S8'), ('action', '|S4'), ('value', '<i4')])
Um die strukturierte Array sortieren könnten Sie die sort
Methode verwenden:
order_array.sort(order=['year', 'month', 'day'])
Für die Arbeit mit strukturierten Arrays müssen Sie einige Unterschiede zwischen homogenen und strukturierten Arrays kennen:
Ihr Original die homogene Anordnung war zweidimensional. Dagegen sind alle strukturierte Arrays sind 1-dimensional:
In [51]: order_array.shape
Out[51]: (8,)
Wenn Sie Index die strukturierte Anordnung mit einem int oder das Array durchlaufen, Sie Zeilen zurück:
In [52]: order_array[3]
Out[52]: (2008, 1, 30, 'GOOG', 'Sell', 100)
Mit homogenen Arrays Sie können auf die Spalten mit order_array[:, i]
zugreifen Nun, mit einem strukturierten Array, greifen Sie auf sie mit Namen: z order_array['year']
.
Oder verwenden Sie Pandas:
Wenn Sie Pandas installieren können, ich denke, könnten Sie am glücklichsten Arbeits mit Pandas Datenrahmen sein:
In [73]: df = pd.DataFrame(rows_list, columns=['date', 'symbol', 'action', 'value'])
In [75]: df.sort(['date'])
Out[75]:
date symbol action value
0 2008-01-23 AAPL Buy 100
2 2008-01-23 GOOG Buy 100
1 2008-01-30 AAPL Sell 100
3 2008-01-30 GOOG Sell 100
6 2008-05-01 XOM Buy 100
7 2008-05-08 XOM Sell 100
4 2008-09-08 GOOG Buy 100
5 2008-09-15 GOOG Sell 100
Pandas hat nützliche Funktionen für Zeitreihen Ausrichten nach Datum, fehlende Angabe Werte, gruppieren und aggregieren/transformieren Zeilen oder Spalten.
In der Regel ist es sinnvoller, eine einzige Datumsspalte anstelle von drei ganzzahligen Spalten für das Jahr, den Monat und den Tag zu verwenden.
Wenn Sie das Jahr, den Monat, den Tag als separate Spalten für die Zwecke der outputing benötigen, zu sagen, csv, dann können Sie die Datumsspalte mit Jahr, Monat, Tag Spalten wie folgt ersetzen:
In [33]: df = df.join(df['date'].apply(lambda x: pd.Series([x.year, x.month, x.day], index=['year', 'month', 'day'])))
In [34]: del df['date']
In [35]: df
Out[35]:
symbol action value year month day
0 AAPL Buy 100 2008 1 23
1 GOOG Buy 100 2008 1 23
2 AAPL Sell 100 2008 1 30
3 GOOG Sell 100 2008 1 30
4 XOM Buy 100 2008 5 1
5 XOM Sell 100 2008 5 8
6 GOOG Buy 100 2008 9 8
7 GOOG Sell 100 2008 9 15
Wenn Sie die Spalte "Datum" nicht verwenden, können Sie natürlich rows_list
allein lassen und den DataFrame mit den Spalten Jahr, Monat und Tag von Anfang an erstellen. Das Sortieren ist immer noch einfach:
df.sort(['year', 'month', 'day'])
möglich Duplikat [Sortieren einer 2D numpy Array von mehreren Achsen] (http://stackoverflow.com/questions/2706605/sorting-a-2d-numpy-array-by-multiple -axes) Verwenden Sie diese Antwort, aber verwenden Sie einen dtype, der für Ihre Daten (nicht alle Strings) sinnvoll ist, z 'dt = dt = [('y', np.uint32), ('m', np.uint32), ('d', np.uint32), ('sym', 'S4'), ('bs' , 'S4'), ('huh', np.uint32)] ' – askewchan