2011-08-11 33 views
62

Tôi có một tập lệnh lớn bằng Python. Tôi lấy cảm hứng từ mã của người khác vì vậy tôi đã sử dụng mô-đun numpy.random cho một số thứ (ví dụ để tạo một dãy số ngẫu nhiên được lấy từ phân phối nhị thức) và ở những nơi khác tôi sử dụng mô-đun random.random.Sự khác nhau giữa numpy.random và random.random trong Python

Ai đó có thể cho tôi biết sự khác biệt chính giữa hai loại này không? Nhìn vào trang web doc cho mỗi một trong hai dường như với tôi rằng numpy.random chỉ có nhiều phương pháp hơn, nhưng tôi không rõ ràng về cách tạo ra các số ngẫu nhiên khác nhau.

Lý do tại sao tôi hỏi là vì tôi cần để gieo rắc chương trình chính của tôi cho mục đích gỡ lỗi. Nhưng nó không hoạt động trừ khi tôi sử dụng cùng một bộ tạo số ngẫu nhiên trong tất cả các mô-đun mà tôi đang nhập, điều này có đúng không?

Ngoài ra, tôi đọc ở đây, trong một bài đăng khác, một cuộc thảo luận về KHÔNG sử dụng numpy.random.seed(), nhưng tôi đã không thực sự hiểu tại sao đây là một ý tưởng tồi. Tôi thực sự sẽ đánh giá cao nếu có ai đó giải thích cho tôi tại sao lại như vậy.

Trả lời

75

Bạn đã thực hiện nhiều quan sát chính xác rồi!

Trừ khi bạn muốn để gieo rắc cả hai máy phát ngẫu nhiên, nó có thể đơn giản hơn trong thời gian dài để lựa chọn một máy phát điện này hay cách khác.

Đối với numpy.random.seed(), khó khăn chính là nó không an toàn cho luồng . Nếu bạn không sử dụng các chủ đề, và nếu bạn có thể mong đợi hợp lý rằng bạn sẽ không cần phải viết lại chương trình của bạn theo cách này trong tương lai, numpy.random.seed() sẽ ổn. Nếu có bất kỳ lý do gì để nghi ngờ rằng bạn có thể cần các chủ đề trong tương lai, thì an toàn hơn trong thời gian dài để làm như được đề xuất và đến make a local instance of the numpy.random.Random class. Theo như tôi có thể nói, random.random.seed() là chủ đề an toàn (hoặc ít nhất, tôi đã không tìm thấy bất kỳ bằng chứng nào ngược lại).

Thư viện numpy.random chứa một vài phân phối xác suất phụ thường được sử dụng trong nghiên cứu khoa học, cũng như một số chức năng tiện lợi để tạo mảng dữ liệu ngẫu nhiên. Thư viện random.random có trọng lượng nhẹ hơn một chút và sẽ tốt nếu bạn không thực hiện nghiên cứu khoa học hoặc các loại công việc khác trong thống kê.

Nếu không, cả hai đều sử dụng số Mersenne twister sequence để tạo số ngẫu nhiên và chúng đều hoàn toàn xác định - nghĩa là, nếu bạn biết một vài bit thông tin chính, có thể dự đoán với độ chắc chắn tuyệt đối what number will come next. Vì lý do này, không phù hợp với bất kỳ serious cryptographic uses nào. Nhưng vì trình tự rất dài, cả hai đều tốt cho việc tạo ra các số ngẫu nhiên trong các chương trình hàng ngày. Đây cũng là lý do cho sự cần thiết phải nhân giống giá trị ngẫu nhiên - nếu bạn bắt đầu ở cùng một vị trí mỗi lần, bạn sẽ luôn nhận được cùng một chuỗi các số ngẫu nhiên!

Là một mặt lưu ý, nếu bạn làm cần mức độ ngẫu nhiên mật mã, bạn nên sử dụng các mô-đun secrets, hoặc một cái gì đó giống như Crypto.Random nếu bạn đang sử dụng một phiên bản Python sớm hơn so với Python 3.6.

+9

Là một lưu ý hàng xa có liên quan, đôi khi neccesary sử dụng * không *, kể từ khi twister Mersenne không tạo chuỗi ngẫu nhiên của entropy đủ để mã hóa (và một số mục đích khoa học khác thường). Trong những trường hợp hiếm hoi này, bạn thường cần [Crypto.Random] (https://www.dlitz.net/software/pycrypto/apidoc/Crypto.Random.random-module.html), có thể sử dụng các nguồn entropy cụ thể của hệ điều hành để tạo ra các chuỗi ngẫu nhiên không xác định có chất lượng cao hơn nhiều so với chỉ có sẵn từ 'random.random'. Bạn thường không cần điều này, mặc dù. – SingleNegationElimination

+0

Cảm ơn bạn Hannnele. Thông tin chi tiết của bạn thực sự rất hữu ích! Nó chỉ ra rằng tôi không thể lấy đi bằng cách sử dụng ONLY một bộ tạo số ngẫu nhiên duy nhất, (cần phải được numpy vì ngẫu nhiên không tạo ra các bản phân phối nhị thức) bởi vì các phần của chương trình của tôi gọi một chương trình khác sử dụng ngẫu nhiên. Tôi sẽ phải gieo hạt cho hai máy phát điện. – Laura

+1

"nếu bạn biết số nào bạn có bây giờ, có thể dự đoán với sự chắc chắn tuyệt đối số lượng sẽ đến tiếp theo." Tôi nghĩ rằng tuyên bố này có thể cần một số làm rõ. Điều gì có nghĩa là nếu bạn biết * trạng thái bên trong * của bộ tạo, bạn có thể tái tạo trình tự - đó là những gì bạn làm khi bạn gieo hạt máy phát điện. Với một đầu ra số duy nhất từ ​​máy phát, bạn không thể dự đoán số tiếp theo. Khoảng thời gian quá lớn, bạn có thể sẽ cần một chuỗi số dài trước khi bạn có thể tính toán vị trí của bạn trên chuỗi giả ngẫu nhiên và do đó dự đoán chuỗi tiếp theo. –

3

Nguồn gốc của các hạt giống và hồ sơ cá nhân phân phối sử dụng sẽ ảnh hưởng đến kết quả đầu ra - nếu bạn đang tìm kiếm ngẫu nhiên cryptgraphic, gieo mầm từ os.urandom() sẽ nhận được các byte ngẫu nhiên gần như thực tế từ thiết bị (tức là ethernet hoặc đĩa) (tức là/dev/random trên BSD)

điều này sẽ tránh bạn tạo ra hạt giống và tạo ra các số ngẫu nhiên xác định. Tuy nhiên, các cuộc gọi ngẫu nhiên sau đó cho phép bạn khớp các con số với một phân phối (cái mà tôi gọi là ness ngẫu nhiên khoa học - cuối cùng tất cả những gì bạn muốn là phân phối đường cong chuông của các số ngẫu nhiên, gọn gàng là tốt nhất để giải quyết vấn đề này. với một máy phát điện, nhưng quyết định những gì ngẫu nhiên bạn muốn - ngẫu nhiên, nhưng defitniely từ một đường cong distrubtuion, hoặc là ngẫu nhiên như bạn có thể có được mà không cần một thiết bị lượng tử

+0

Cảm ơn Paul rất nhiều, câu trả lời của bạn thực sự hữu ích! Tôi không tìm kiếm sự ngẫu nhiên mật mã, tôi đang làm mô hình toán học và các số giả ngẫu nhiên là đủ cho tôi. Nó chỉ ra tôi không thể dính vào một máy phát điện như tôi muốn kể từ khi tôi cần numpy cho việc phân phối nhị thức và chương trình của tôi gọi một chương trình khác sử dụng ngẫu nhiên: ( – Laura

3

từ Python for Data Analysis, module numpy.random bổ sung các Python random với các chức năng cho hiệu quả. tạo toàn bộ mảng các giá trị mẫu từ nhiều loại phân phối xác suất.

Ngược lại, mô-đun random được tích hợp sẵn của Python chỉ lấy mẫu một giá trị tại một thời điểm, trong khi numpy.random có thể tạo mẫu rất lớn nhanh hơn. Sử dụng IPython diệu chức năng %timeit ai có thể xem những mô-đun thực hiện nhanh hơn:

In [1]: from random import normalvariate 
In [2]: N = 1000000 

In [3]: %timeit samples = [normalvariate(0, 1) for _ in xrange(N)] 
1 loop, best of 3: 963 ms per loop 

In [4]: %timeit np.random.normal(size=N) 
10 loops, best of 3: 38.5 ms per loop 
Các vấn đề liên quan