TLDR: NumPy brilla fare calcoli numerici su array numerici. Sebbene sia possibile (vedi sotto) NumPy non è adatto per questo. Probabilmente stai meglio usando Pandas.
Conversione di dtype da string-dtype a dtype numerico richiede allocazione dello spazio per un nuovo array. Pertanto, probabilmente starai meglio rivedendo il modo in cui stai creando order_array
dall'inizio.
È interessante notare che, anche se è stato convertito i valori da interi, quando si chiama
È possibile controllare la DTYPE per te ispezionando order_array.dtype
:
In [42]: order_array = np.array(rows_list)
In [43]: order_array.dtype
Out[43]: dtype('|S4')
Ora, come possiamo risolvere questo problema?
Utilizzando un DTYPE oggetto:
Il modo più semplice è quello di utilizzare un 'oggetto' 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)
Il problema qui è che np.lexsort
o np.sort
non funzionano su array di dtype object
. Per ovviare a questo problema, si poteva ordinare la rows_list
prima di creare 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')
Una soluzione migliore sarebbe quella di combinare le prime tre colonne in datetime.date oggetti:
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)
Anche se questo è semplice, non mi piacciono gli array NumPy dell'oggetto dtype. Non si ottengono né la velocità né la memoria risparmiando spazio per gli array NumPy con i dtypes nativi . A questo punto si potrebbe trovare che lavorare con un elenco Python degli elenchi più rapido e sintatticamente più facile da gestire.
Utilizzando una matrice strutturato:
Una soluzione più NumPy-ish che offre ancora prestazioni di velocità e la memoria è utilizzare un structured array (al contrario di matrice omogenea). Per fare una serie strutturato con np.array
avrete bisogno di fornire una DTYPE esplicitamente:
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')])
per ordinare l'array strutturato è possibile utilizzare il metodo sort
:
order_array.sort(order=['year', 'month', 'day'])
Per eseguire operazioni array strutturati, è necessario conoscere alcune differenze tra array omogenei e strutturati:
Il tuo originale la matrice omogenea era bidimensionale. Al contrario, tutti array strutturati sono 1-dimensionale:
In [51]: order_array.shape
Out[51]: (8,)
Se indice dell'array strutturato con un int o scorrere la matrice, è restituiti righe:
In [52]: order_array[3]
Out[52]: (2008, 1, 30, 'GOOG', 'Sell', 100)
Con matrici omogenee puoi accedere alle colonne con order_array[:, i]
Ora, con un array strutturato, puoi accedervi per nome: es. order_array['year']
.
In alternativa, utilizzare Panda:
Se è possibile installare Pandas, penso che si potrebbe essere più felice di lavoro con un Pandas dataframe:
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
Panda dispone di funzioni utili per l'allineamento timeseries per data, compilando i valori mancanti , raggruppando e aggregando/trasformando righe o colonne.
In genere è più utile avere una sola colonna della data, invece di tre colonne valori interi per l'anno, mese, giorno.
Se avete bisogno di anno, mese, giorno colonne come distinti ai fini di outputing, per dire csv, quindi è possibile sostituire la colonna data con anno, mese, colonne giornata come questa:
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
Oppure, se non si ha alcun uso per la colonna 'data', si può ovviamente lasciare rows_list
da solo e creare il DataFrame con le colonne anno, mese, giorno dall'inizio. L'ordinamento è ancora facile:
df.sort(['year', 'month', 'day'])
possibile duplicato di [Ordinamento 2D matrice NumPy da più assi] (http://stackoverflow.com/questions/2706605/sorting-a-2d-numpy-array-by-multiple -axes) Usa quella risposta, ma usa un dtype che abbia senso per i tuoi dati (non tutte le stringhe), ad es 'dt = dt = [('y', np.uint32), ('m', np.uint32), ('d', np.uint32), ('sym', 'S4'), ('bs' , 'S4'), ('huh', np.uint32)] ' – askewchan