2011-09-09 40 views
5

Tôi thấy mình phân tích rất nhiều tệp dữ liệu (thường là trong tệp .csv hoặc tương tự) bằng trình đọc csv và vòng lặp for lặp lại trên mỗi dòng. Các dữ liệu thường là một bảng nổi như vậy ví dụ.Cách Pythonic để điền vào mảng numpy

reader = csv.reader(open('somefile.csv')) 
header = reader.next() 

res_list = [list() for i in header]  

for line in reader: 
    for i in range(len(line)): 
    res_list[i].append(float(line[i])) 

result_dict = dict(zip(header,res_list)) #so we can refer by column title 

Đây là một cách ok để cư vì vậy tôi nhận được mỗi cột như một danh sách riêng biệt tuy nhiên, tôi muốn rằng nơi chứa dữ liệu mặc định cho danh sách các mục (và danh sách lồng nhau) là mảng NumPy, vì 99 lần ra 100 số được bơm vào các kịch bản/chức năng xử lý khác nhau và có sức mạnh của các danh sách gọn gàng làm cho cuộc sống của tôi dễ dàng hơn.

Numpy append(arr, item) không nối thêm tại chỗ và do đó sẽ yêu cầu tạo lại mảng cho mọi điểm trong bảng (chậm và không cần thiết). Tôi cũng có thể lặp qua danh sách các cột dữ liệu và bọc chúng vào một mảng sau khi tôi hoàn thành (đó là những gì tôi đã làm), nhưng đôi khi nó không được cắt rõ ràng như vậy về khi Tôi đã hoàn tất phân tích cú pháp tệp và có thể cần phải chắp thêm nội dung vào danh sách sau đó xuống dòng. Tôi đã tự hỏi nếu có một số cách ít lò hơi hơn (sử dụng cụm từ được sử dụng quá mức "pythonic") để xử lý các bảng dữ liệu theo cách tương tự, hoặc để cư trú mảng (nơi chứa cơ sở là một danh sách) tự động và không có mảng sao chép mọi lúc.

(Lưu ý khác: loại gây phiền nhiễu khi nói chung mọi người sử dụng cột để tổ chức dữ liệu nhưng csv đọc theo hàng nếu người đọc kết hợp đối số read_column (có, tôi biết nó sẽ không siêu hiệu quả), tôi nghĩ nhiều người sẽ tránh việc mã tấm nồi hơi như ở trên để phân tích một tệp dữ liệu csv)

Trả lời

7

numpy.loadtxt:.

X = numpy.loadtxt('somefile.csv', delimiter=',') 

Documentation.


Edit: cho một danh sách các mảng NumPy,

X = [scipy.array(line.split(','), dtype='float') 
    for line in open('somefile.csv', 'r')] 
+1

tôi đã xem xét này trước đây, nhưng nó có một số vấn đề, đặc biệt là nó đòi hỏi rằng chiều dài hàng là như nhau xuống mảng. Mặc dù đoạn mã nhỏ của tôi giả định rằng nó không phải lúc nào cũng xảy ra (ví dụ: các hàng trống để chỉ ra các ngắt giữa các cụm thu thập dữ liệu). – crasic

+0

Nếu tôi hiểu chính xác - hãy xem chỉnh sửa. –

2

Tôi nghĩ rằng đó là khó khăn để cải thiện rất nhiều vào những gì bạn có. Danh sách Python tương đối rẻ để xây dựng và nối thêm; Các mảng NumPy đắt hơn để tạo và không cung cấp phương thức .append(). Vì vậy, đặt cược tốt nhất của bạn là xây dựng các danh sách như bạn đang làm, và sau đó ép buộc đến np.array() khi thời gian đến.

Một vài điểm nhỏ:

  • Nó là hơi nhanh hơn để sử dụng [] để tạo ra một danh sách hơn để gọi list(). Đây là một số lượng nhỏ thời gian chạy của chương trình mà bạn có thể cảm thấy tự do để bỏ qua điểm này.

  • Khi bạn không thực sự sử dụng chỉ mục vòng lặp, bạn có thể sử dụng _ cho tên biến để ghi lại điều này.

  • Thường tốt hơn để lặp qua chuỗi hơn là tìm độ dài của chuỗi, hãy xây dựng một range() và sau đó lập chỉ mục chuỗi rất nhiều. Bạn có thể sử dụng enumerate() để có chỉ mục nếu bạn cũng cần chỉ mục.

Đặt chúng lại với nhau và tôi nghĩ đây là phiên bản được cải thiện một chút. Nhưng nó gần như không thay đổi so với bản gốc của bạn, và tôi không thể nghĩ ra bất kỳ cải tiến thực sự tốt nào.

reader = csv.reader(open('somefile.csv')) 
header = reader.next() 

res_list = [ [] for _ in header] 

for row in reader: 
    for i, val in enumerate(row): 
     res_list[i].append(float(val)) 

# build dict so we can refer by column title 
result_dict = dict((n, res_list[i]) for i, n in enumerate(header)) 
+0

"NumPy ... không cung cấp phương thức .append() ở tất cả" NumPy chắc chắn có phương thức chắp thêm. Nó hoạt động nhiều hơn hoặc ít hơn như python append ngoại trừ nó không phải là "tại chỗ". – doug

+0

@doug: 'a = np.array (phạm vi (3))' thành công. Sau đó, 'a.append (4)' đưa ra thông báo 'AttributeError: 'numpy.ndarray' đối tượng không có thuộc tính 'append''. Nếu các mảng NumPy có phương thức '.append()', thì tôi đang làm gì sai ở đây? – steveha

+0

vì vậy hãy thử điều này: a = NP.random.randint (0, 10, 5); a = NP.append (a, [2, 3]). Vì vậy, NumPy có một phụ * chức năng * không phải là một phương pháp phụ thêm - mà làm cho tuyên bố của bạn trong câu trả lời của bạn ở trên hoàn toàn chính xác! – doug

2

Để tải một cách hiệu quả dữ liệu đến một NumPy Arraya, tôi thích fromiter chức năng NumPy của.

lợi thế trong bối cảnh này:

  • dòng giống như bốc,

  • trước xác định kiểu dữ liệu của mảng reesult, và

  • tiền phân bổ rỗng mảng đầu ra, sau đó dân cư với luồng từ lần lặp lại.

Đầu tiên trong số này là inherent-- fromiter chỉ chấp nhận đầu vào dữ liệu ở dạng iterable - người cuối cùng hai được quản lý thông qua các đối số thứ hai và thứ ba truyền cho fromiter, dtype,đếm.

>>> import numpy as NP 
>>> # create some data to load: 
>>> import random 
>>> source_iterable = (random.choice(range(100)) for c in range(20)) 

>>> target = NP.fromiter(source_iterable, dtype=NP.int8, count=v.size) 
>>> target 
     array([85, 28, 37, 4, 23, 5, 47, 17, 78, 40, 28, 5, 69, 47, 15, 92, 
      41, 33, 33, 98], dtype=int8) 

Nếu bạn không muốn tải dữ liệu của bạn sử dụng một iterable, bạn vẫn có thể tiền cấp phát bộ nhớ cho mảng mục tiêu của bạn, bằng cách sử dụng chức năng NumPy trốngempty_like

>>> source_vec = NP.random.rand(10) 
>>> target = NP.empty_like(source_vec) 
>>> target[:] = source_vec 
>>> target 
    array([ 0.5472, 0.5085, 0.0803, 0.4757, 0.4831, 0.3054, 0.1024, 
      0.9073, 0.6863, 0.3575]) 

Hoặc, bạn có thể tạo một mảng trống (được phân bổ trước) bằng cách gọi trống, sau đó chỉ cần chuyển vào hình dạng bạn muốn. Chức năng này, ngược lại với empty_like, cho phép của bạn vượt qua trong các kiểu dữ liệu:

>>> target = NP.empty(shape=s.shape, dtype=NP.float) 
>>> target 
    array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) 
>>> target[:] = source 
>>> target 
    array([ 0.5472, 0.5085, 0.0803, 0.4757, 0.4831, 0.3054, 0.1024, 
      0.9073, 0.6863, 0.3575]) 
+0

+1 cho np.từ ngữ – tdc

Các vấn đề liên quan