tldr: NumPy chiếu sáng khi thực hiện tính toán số trên mảng số. Mặc dù có thể (xem bên dưới) NumPy không phù hợp với điều này. Có lẽ bạn nên sử dụng Pandas tốt hơn.
Chuyển đổi loại dtypes từ chuỗi dtype thành dtype dạng số yêu cầu phân bổ không gian cho mảng mới. Do đó, có thể bạn nên cải thiện cách bạn đang tạo order_array
ngay từ đầu.
Bạn có thể kiểm tra dtype cho chính mình bằng cách kiểm tra order_array.dtype
:
In [42]: order_array = np.array(rows_list)
In [43]: order_array.dtype
Out[43]: dtype('|S4')
Bây giờ, làm thế nào để chúng tôi sửa lỗi này?
Sử dụng một dtype đối tượng:
Cách đơn giản nhất là sử dụng một 'đối tượng' 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)
Vấn đề ở đây là np.lexsort
hoặc np.sort
không làm việc trên mảng của dtype object
. Để khắc phục vấn đề đó, bạn có thể sắp xếp các rows_list
trước khi tạo 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')
Một lựa chọn tốt hơn là nên kết hợp ba cột đầu tiên vào datetime.date đối tượng:
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)
Mặc dù đây là đơn giản, tôi không thích mảng NumPy của đối tượng dtype. Bạn không nhận được tốc độ cũng như mức độ tiết kiệm không gian bộ nhớ của các mảng NumPy với kiểu gốc. Tại thời điểm này, bạn có thể tìm cách làm việc với danh sách các danh sách của Python nhanh hơn và dễ dàng hơn về cú pháp để giải quyết.
Sử dụng một mảng cấu trúc:
Một giải pháp nữa NumPy-ish mà vẫn mang lại lợi ích tốc độ và bộ nhớ là sử dụng một structured array (như trái ngược với mảng đồng nhất). Để thực hiện một mảng cấu trúc với np.array
bạn sẽ cần phải cung cấp một dtype một cách rõ ràng:
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')])
Để sắp xếp các mảng cấu trúc, bạn có thể sử dụng phương pháp sort
:
order_array.sort(order=['year', 'month', 'day'])
Để làm việc với mảng có cấu trúc, bạn sẽ cần phải biết về một số khác biệt giữa mảng thuần nhất và có cấu trúc:
Bản gốc của bạn mảng đồng nhất là 2 chiều. Ngược lại, tất cả mảng cấu trúc là 1 chiều:
In [51]: order_array.shape
Out[51]: (8,)
Nếu bạn chỉ số mảng cấu trúc với một int hoặc lặp qua mảng, bạn nhận lại hàng:
In [52]: order_array[3]
Out[52]: (2008, 1, 30, 'GOOG', 'Sell', 100)
Với mảng đồng nhất bạn có thể truy cập các cột với order_array[:, i]
Bây giờ, với một mảng có cấu trúc, bạn truy cập chúng theo tên: ví dụ order_array['year']
.
Hoặc, sử dụng Pandas:
Nếu bạn có thể cài đặt Pandas, tôi nghĩ bạn có thể làm việc hạnh phúc nhất với một 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
Pandas có chức năng hữu ích cho việc sắp xếp chuỗi thời gian theo ngày, điền vào các giá trị thiếu , nhóm và tổng hợp/chuyển đổi hàng hoặc cột.
Thường thì hữu ích hơn khi có cột ngày đơn thay vì ba cột có giá trị nguyên cho năm, tháng, ngày.
Nếu bạn cần năm, tháng, ngày cột như riêng biệt với mục đích outputing, để nói csv, sau đó bạn có thể thay thế các cột ngày với năm tháng, cột, ngày như thế này:
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
Hoặc, nếu bạn không sử dụng cột 'ngày' để bắt đầu, bạn có thể chỉ để riêng rows_list
và xây dựng DataFrame với các cột năm, tháng, ngày từ đầu. Sắp xếp là vẫn dễ dàng:
df.sort(['year', 'month', 'day'])
thể trùng lặp của [Sắp xếp một mảng NumPy 2D bằng nhiều trục] (http://stackoverflow.com/questions/2706605/sorting-a-2d-numpy-array-by-multiple -axes) Sử dụng câu trả lời đó, nhưng sử dụng một loại dtype có ý nghĩa cho dữ liệu của bạn (không phải tất cả các chuỗi), ví dụ 'dt = dt = [('y', np.uint32), ('m', np.uint32), ('d', np.uint32), ('sym', 'S4'), ('bs') , 'S4'), ('huh', np.uint32)] ' – askewchan