2010-02-16 35 views
13

Tôi muốn lấy danh sách dữ liệu chứa trong thùng biểu đồ. Tôi đang sử dụng numpy, và Matplotlib. Tôi biết cách di chuyển dữ liệu và kiểm tra các cạnh của thùng. Tuy nhiên, tôi muốn làm điều này cho một biểu đồ 2D và mã để làm điều này là khá xấu xí. Có numpy có bất kỳ cấu trúc để làm cho điều này dễ dàng hơn?Cách lấy dữ liệu trong thùng biểu đồ

Đối với trường hợp 1D, tôi có thể sử dụng searchsorted(). Nhưng logic không tốt hơn nhiều, và tôi không thực sự muốn tìm kiếm nhị phân trên mỗi điểm dữ liệu khi tôi không phải làm vậy.

Hầu hết các logic khó chịu là do các vùng ranh giới bin. Tất cả các vùng đều có ranh giới như thế này: [cạnh trái, cạnh phải). Ngoại trừ thùng cuối cùng, có một khu vực như thế này: [cạnh trái, cạnh phải].

Dưới đây là một số mẫu mã đối với trường hợp 1D:

import numpy as np 

data = [0, 0.5, 1.5, 1.5, 1.5, 2.5, 2.5, 2.5, 3] 

hist, edges = np.histogram(data, bins=3) 

print 'data =', data 
print 'histogram =', hist 
print 'edges =', edges 

getbin = 2 #0, 1, or 2 

print '---' 
print 'alg 1:' 

#for i in range(len(data)): 
for d in data: 
    if d >= edges[getbin]: 
     if (getbin == len(edges)-2) or d < edges[getbin+1]: 
      print 'found:', d 
     #end if 
    #end if 
#end for 

print '---' 
print 'alg 2:' 

for d in data: 
    val = np.searchsorted(edges, d, side='right')-1 
    if val == getbin or val == len(edges)-1: 
     print 'found:', d 
    #end if 
#end for 

Dưới đây là một số mẫu mã đối với trường hợp 2D:

import numpy as np 

xdata = [0, 1.5, 1.5, 2.5, 2.5, 2.5, \ 
     0.5, 0.5, 0.5, 0.5, 1.5, 1.5, 1.5, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, \ 
     0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 3] 
ydata = [0, 5,5, 5, 5, 5, \ 
     15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \ 
     25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 30] 

xbins = 3 
ybins = 3 
hist2d, xedges, yedges = np.histogram2d(xdata, ydata, bins=(xbins, ybins)) 

print 'data2d =', zip(xdata, ydata) 
print 'hist2d =' 
print hist2d 
print 'xedges =', xedges 
print 'yedges =', yedges 

getbin2d = 5 #0 through 8 

print 'find data in bin #', getbin2d 

xedge_i = getbin2d % xbins 
yedge_i = int(getbin2d/xbins) #IMPORTANT: this is xbins 

for x, y in zip(xdata, ydata): 
    # x and y left edges 
    if x >= xedges[xedge_i] and y >= yedges[yedge_i]: 
     #x right edge 
     if xedge_i == xbins-1 or x < xedges[xedge_i + 1]: 
      #y right edge 
      if yedge_i == ybins-1 or y < yedges[yedge_i + 1]: 
       print 'found:', x, y 
      #end if 
     #end if 
    #end if 
#end for 

Có một trình dọn dẹp/cách hiệu quả hơn để làm điều này? Nó có vẻ như một cái gì đó sẽ có thứ gì đó cho việc này.

+3

Chỉ cần ra khỏi tò mò; tại sao bạn sử dụng các nhận xét như #end nếu trong mã của bạn? "Mỗi điểm ảnh đếm" Bằng cách làm điều đó bạn đang bỏ qua mục đích của thụt đầu dòng. –

+3

2 lý do. Tôi là một nhà phát triển C++ đầu tiên, và một nhà phát triển python thứ hai. Việc thiếu niềng răng của Python làm tôi khó chịu. Khi tôi có các khối mã phức tạp với nhiều sự thụt lề khác nhau, tôi không muốn đếm khoảng trắng. Và tôi làm hầu hết sự phát triển của tôi trong Emacs. Bằng cách đặt các bình luận đóng trên các khối mã, nó cho phép tôi nhấn TAB trên mọi dòng và Emacs sẽ không cố gắng làm sai một cái gì đó. – Ben

Trả lời

21

digitize, từ cốt lõi NumPy, sẽ cung cấp cho bạn index của bin mà mỗi giá trị trong biểu đồ của bạn thuộc:

import numpy as NP 
A = NP.random.randint(0, 10, 100) 

bins = NP.array([0., 20., 40., 60., 80., 100.]) 

# d is an index array holding the bin id for each point in A 
d = NP.digitize(A, bins)  
+0

Điều này gần như hoàn hảo! Nếu có bất kỳ devs sumpy ở đây, chức năng này thực sự nên đi vào phần "xem thêm" của tài liệu biểu đồ. Thật là quá tệ khi logic bin số hóa() không khớp chính xác với lôgic bin(). Vì vậy, điều này dẫn đến chỉ là mã vụng về như phần còn lại của các ví dụ của tôi ở trên. – Ben

+1

không phải là chính xác này giống như 'bins.searchsorted (A, 'right')'? –

4

thế nào về một cái gì đó như:

In [1]: data = numpy.array([0, 0.5, 1.5, 1.5, 1.5, 2.5, 2.5, 2.5, 3]) 
In [2]: hist, edges = numpy.histogram(data, bins=3) 
In [3]: for l, r in zip(edges[:-1], edges[1:]): 
    print(data[(data > l) & (data < r)]) 
    ....:  
    ....:  
[ 0.5] 
[ 1.5 1.5 1.5] 
[ 2.5 2.5 2.5] 
In [4]: 

với một chút mã để xử lý các trường hợp cạnh.

0

pyplot.hist trong matplotlib tạo biểu đồ (nhưng cũng vẽ nó vào màn hình mà bạn có thể không muốn). Chỉ với các thùng, bạn có thể sử dụng numpy.histogram, như được nêu trong một câu trả lời khác.

Here là ví dụ so sánh pyploy.hist và numpy.histogram.

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