Vấn đề có vẻ phát sinh nếu cuộc gọi đầu tiên đến hàm sinh tồn nằm trong phạm vi rõ ràng là bằng không (xem nhận xét của tôi về câu trả lời trước). Ví dụ, đối với các cuộc gọi đến hypergeom.sf (x, M, n, N) nó sẽ thất bại nếu lệnh gọi hàm hypergeometric đầu tiên đến hàm là một tình huống trong đó x> n, trong đó hàm sống sẽ luôn bằng không.
Bạn trivially có thể sửa lỗi này tạm thời bởi:
def new_hypergeom_sf(k, *args, **kwds):
from scipy.stats import hypergeom
(M, n, N) = args[0:3]
try:
return hypergeom.sf(k, *args, **kwds)
except Exception as inst:
if k >= n and type(inst) == IndexError:
return 0 ## or conversely 1 - hypergeom.cdf(k, *args, **kwds)
else:
raise inst
Bây giờ nếu bạn không có vấn đề chỉnh sửa /usr/share/pyshared/scipy/stats/distributions.py (hoặc tập tin tương đương), sửa chữa có khả năng trên đường dây 3966 nơi ngay bây giờ nó đọc:
place(output,cond,self._sf(*goodargs))
if output.ndim == 0:
return output[()]
return output
Nhưng nếu bạn thay đổi nó thành:
if output.ndim == 0:
return output[()]
place(output,cond,self._sf(*goodargs))
if output.ndim == 0:
return output[()]
return output
Nó bây giờ hoạt động mà không có IndexError. Về cơ bản, nếu đầu ra là không chiều bởi vì nó không kiểm tra, nó cố gắng gọi địa điểm, không thành công và không tạo ra phân phối. (Điều này không xảy ra nếu một phân phối trước đó đã được tạo ra có khả năng là lý do tại sao điều này không bị bắt gặp trong các bài kiểm tra trước đó.) Lưu ý rằng địa điểm (được định nghĩa trong function_base.py của numpy) sẽ thay đổi các phần tử của mảng (mặc dù tôi không chắc chắn nếu nó thay đổi kích thước) vì vậy nó có thể là tốt nhất để vẫn có nó để lại 0 dim kiểm tra sau khi diễn ra quá. Tôi đã không kiểm tra đầy đủ điều này để xem sự thay đổi này có phá vỡ bất kỳ thứ gì khác không (và nó áp dụng cho tất cả các bản phân phối biến ngẫu nhiên rời rạc), vì vậy nó có thể là tốt nhất để sửa lỗi đầu tiên.
Nó phá vỡ nó; ví dụ: stats.hypergeom.sf (1,10,2,5) trả về 0 (thay vì 2/9).
sửa chữa Điều này dường như làm việc tốt hơn nhiều, trong phần giống nhau:
class rv_discrete(rv_generic):
...
def sf(self, k, *args, **kwds):
...
if any(cond):
place(output,cond,self._sf(*goodargs))
if output.ndim == 0:
return output[()]
return output
Nó cũng làm như vậy trên Python 2.6.6 trên Debian. – eumiro
Đối với bất cứ điều gì nó có giá trị, điều này nghe có vẻ như nó có thể là một lỗi, và do đó có thể được yêu cầu tốt hơn trên danh sách người dùng scipy: http://mail.scipy.org/mailman/listinfo/scipy-user Nó có nhiều khả năng để có được sự chú ý của các nhà phát triển ở đó ... –
Tôi đã mở một vé cho việc này: http://projects.scipy.org/scipy/ticket/1291. Như Joe Kington đã đề cập, sẽ hữu ích khi báo cáo lỗi hoặc hành vi bất ngờ đến danh sách gửi thư hoặc trình theo dõi lỗi của gói. – user333700