2013-06-04 30 views
5

Vì vậy, tôi có danh sách các từ và tôi cần phải biết tần suất mỗi từ xuất hiện trên mỗi danh sách. Sử dụng ".count (word)" hoạt động, nhưng nó quá chậm (mỗi danh sách có hàng ngàn từ và tôi có hàng ngàn danh sách).Tôi có thể lừa numpy.histogram thành hành vi như numpy.bincount không?

Tôi đã cố gắng tăng tốc mọi thứ với sự khó khăn. Tôi tạo ra một mã số duy nhất cho mỗi từ, vì vậy tôi có thể sử dụng numpy.bincount (vì nó chỉ hoạt động với số nguyên, không phải chuỗi). Nhưng tôi nhận được "ValueError: mảng quá lớn".

Vì vậy, bây giờ tôi đang cố gắng để tinh chỉnh đối số "thùng" của hàm numpy.histogram để làm cho nó trả về số đếm tần số tôi cần (bằng cách nào đó numpy.histogram dường như không gặp rắc rối với mảng lớn). Nhưng cho đến nay không tốt. Bất cứ ai ra khỏi đó sẽ xảy ra để làm điều này trước đây? Thậm chí có thể không? Có một số giải pháp đơn giản hơn mà tôi không thấy?

+0

Mảng lớn của bạn thế nào !? Tôi chỉ sử dụng bincount với một mảng dài 10000000 ints và nó hoạt động tốt. Tôi hết bộ nhớ trước khi tôi gặp lỗi bạn làm. –

+1

Tôi nghĩ rằng vấn đề ở đây liên quan đến hệ thống mã số duy nhất của bạn, không phải kích thước của các mảng ban đầu. np.bincount sẽ tạo một mảng có độ dài bằng 1 + số nguyên lớn nhất trong mảng của bạn, trong đó, nếu bạn đang sử dụng một số loại mã hóa với số lượng lớn ridiculously, có thể gây ra một vấn đề. Tuy nhiên, tôi không có vấn đề gì với np.bincount ([1000000000]). Lược đồ mã số của bạn là gì? – cge

+1

Ah có vẻ như lỗi xảy ra khi bạn đang số nguyên bạn đang cố gắng để bin là rất lớn. Bạn có thể mô phỏng nó bằng 'foo = numpy.random.randint (2 ** 62, size = 1000); numpy.bincount (foo) '. Tôi đoán nó đang cố gắng để tạo ra một mảng lớn unindexable để lưu trữ tất cả các thùng và numpy là nói không (lỗi đó là trong 'multiarray/ctors.c'). Bạn có bao nhiêu từ? –

Trả lời

5

Không sử dụng numpy cho việc này. Sử dụng collections.Counter để thay thế. Nó được thiết kế cho trường hợp sử dụng này.

+0

Đây rõ ràng là cách đúng để thực hiện nếu sự cố được mô tả! –

+0

Tuyệt vời! Sạch sẽ và siêu nhanh. – Parzival

4

Tại sao không làm giảm số nguyên của bạn để các thiết lập tối thiểu sử dụng numpy.unique:

original_keys, lookup_vals = numpy.unique(big_int_string_array, return_inverse=True) 

Bạn có thể sau đó chỉ cần sử dụng numpy.bincount trên lookup_vals, và nếu bạn cần phải lấy lại chuỗi gốc số nguyên duy nhất, bạn chỉ có thể sử dụng các giá trị của lookup_vals làm chỉ mục cho original_keys.

Vì vậy, một cái gì đó như:

import binascii 
import numpy 

string_list = ['a', 'b', 'c', 'a', 'b', 'd', 'c'] 
int_list = [binascii.crc32(string)**2 for string in string_list] 

original_keys, lookup_vals = numpy.unique(int_list, return_inverse=True) 

bins = bincount(lookup_vals) 

Ngoài ra, nó tránh được sự cần thiết phải vuông số nguyên của bạn.

1

Thiago, Bạn cũng có thể dùng thử trực tiếp từ các biến phân loại với phương pháp itemfreq của scipy. Dưới đây là ví dụ:

>>> import scipy as sp 
>>> import scipy.stats 
>>> rv = ['do', 're', 'do', 're', 'do', 'mi'] 
>>> note_frequency = sp.stats.itemfreq(rv) 
>>> note_frequency 
array([['do', '3'], 
     ['mi', '1'], 
     ['re', '2']], 
     dtype='|S2')