Sự khác biệt giữa numpy.random và random.random trong Python


100

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 đã kết thúc bằng cách sử dụng numpy.randommô-đun cho một số việc (ví dụ: để tạo một mảng các 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.

Ai đó có thể vui lòng cho tôi biết sự khác biệt chính giữa hai? Nhìn vào trang web tài liệu cho cả hai numpy.randomphương pháp, tôi thấy dường như chỉ có nhiều phương pháp hơn, nhưng tôi không rõ về cách tạo ra các số ngẫu nhiên khác nhau.

Lý do tại sao tôi yêu cầu là bởi vì tôi cần bắt đầu chương trình chính của mình 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 trình 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ó chính xác 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ề việc KHÔNG sử dụng numpy.random.seed(), nhưng tôi không thực sự hiểu tại sao đây lại là một ý tưởng tồi. Tôi thực sự sẽ đánh giá cao nếu ai đó giải thích cho tôi lý do tại sao lại như vậy.

Câu trả lời:


120

Bạn đã thực hiện nhiều quan sát đúng rồi!

Trừ khi bạn muốn gieo cả hai trình tạo ngẫu nhiên, nếu không, về lâu dài, việc chọn một trình tạo này hay trình phát khác có thể đơn giản hơn. Nhưng nếu bạn cần sử dụng cả hai, thì có, bạn cũng sẽ cần gieo cả hai, vì chúng tạo ra các số ngẫu nhiên độc lập với nhau.

Đối với numpy.random.seed(), khó khăn chính là nó không an toàn theo luồng - nghĩa là không an toàn khi sử dụng nếu bạn có nhiều luồng thực thi khác nhau , vì nó không được đảm bảo hoạt động nếu hai luồng khác nhau đang thực thi chức năng cùng một lúc. Nếu bạn không sử dụng các chuỗi và nếu bạn có thể mong đợi một cách hợp lý rằng bạn sẽ không cần phải viết lại chương trình của mình theo cách này trong tương lai, numpy.random.seed()thì không sao cả. Nếu có bất kỳ lý do gì để nghi ngờ rằng bạn có thể cần các luồng trong tương lai, thì về lâu dài sẽ an toàn hơn nhiều nếu làm theo đề xuất và tạo một phiên bản cục bộ của numpy.random.Randomlớp . Theo như tôi có thể nói, random.random.seed()là một chuỗi 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 cho điều ngược lại).

Các numpy.randomthư viện chứa một vài phân phối thêm khả năng thường được sử dụng trong nghiên cứu khoa học, cũng như một vài chức năng thuận tiện cho việc tạo ra các mảng dữ liệu ngẫu nhiên. Các random.randomthư viện là một chút nhẹ hơn, và nên sử dụng tốt nếu bạn không làm nghiên cứu khoa học hoặc các loại công việc trong thống kê.

Mặt khác, cả hai đều sử dụng trình tự xoắn Mersenne để tạo ra các số ngẫu nhiên của chúng và cả hai đều hoàn toàn xác định - nghĩa là, nếu bạn biết một vài thông tin quan trọng, bạn có thể dự đoán một cách chắc chắn tuyệt đối con số nào sẽ đến tiếp theo . Vì lý do này, cả numpy.random và random.random đều không phù hợp cho bất kỳ mục đích sử dụng mật mã nghiêm trọng nào . Nhưng vì trình tự rất dài, nên cả hai đều phù hợp để tạo số ngẫu nhiên trong trường hợp bạn không lo lắng về việc mọi người đang cố gắng thiết kế ngược dữ liệu của bạn. Đây cũng là lý do cần thiết phải gieo giá trị ngẫu nhiên - nếu bạn bắt đầu ở cùng một nơi 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ật mã ngẫu nhiên, bạn nên sử dụng bí mật module, 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.


14
Như một lưu ý liên quan xa, đôi khi cần thiết phải sử dụng cả hai , vì twister Mersenne không tạo ra các chuỗi entropy ngẫu nhiên đủ cho các mục đích mật mã (và một số mục đích khoa học khác thường). Trong những trường hợp hiếm hoi đó, bạn thường cần Crypto.Random , 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 random.random. Bạn thường không cần cái này.
SingleNegationElimination

Cảm ơn Hannnele. Những hiểu biết của bạn thực sự rất hữu ích! Hóa ra là tôi không thể tránh được việc CHỈ sử dụng một trình tạo số ngẫu nhiên duy nhất, (cần phải phức tạp vì ngẫu nhiên không tạo ra phân phối nhị thức) 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 hai máy phát điện.
Laura

2
"nếu bạn biết mình đang có con số nào, có thể dự đoán một cách chắc chắn tuyệt đối con số nào 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 này có nghĩa là nếu bạn biết trạng thái bên trong của máy phát, bạn có thể tái tạo trình tự - đó là những gì bạn làm khi bạn khởi tạo trình tạo. Với một đầu ra số duy nhất từ ​​trình tạo, bạn không thể dự đoán số tiếp theo. Khoảng thời gian này quá lớn, bạn có thể sẽ cần một dãy số dài trước khi có thể tính toán vị trí của bạn trên dãy số giả ngẫu nhiên và do đó dự đoán dãy số tiếp theo.
Kaushik Ghose

12

Từ Python cho Phân tích Dữ liệu , mô-đun numpy.randombổ sung cho Python randomcác hàm để tạo hiệu quả toàn bộ mảng giá trị mẫu từ nhiều loại phân phối xác suất.

Ngược lại, randommô-đun tích hợp của Python chỉ lấy mẫu một giá trị tại một thời điểm, trong khi numpy.randomcó thể tạo mẫu rất lớn nhanh hơn. Sử dụng chức năng ma thuật IPython, %timeitngười ta có thể thấy mô-đun nào hoạt động 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

1
Không phải là trường hợp cho các phương pháp khác. so np.random.randint(2)với random.randrange(2)và NumPy chậm hơn . NumPy: 1,25 us và Random: 891 ns. Và cũng có quan hệ tương tự cho np.random.rand()random.random().
Shayan Amani

3

Nguồn của hạt giống và cấu hình phân phối được sử dụng sẽ ảnh hưởng đến kết quả đầu ra - nếu bạn đang tìm kiếm sự ngẫu nhiên bằng mật mã, việc gieo hạt từ os.urandom () sẽ nhận được các byte gần như ngẫu nhiên thực từ bộ điều khiển 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 đưa ra một hạt giống và do đó tạo ra các số ngẫu nhiên xác định. Tuy nhiên, các lệnh gọi ngẫu nhiên sau đó cho phép bạn điều chỉnh các số với một phân phối (cái mà tôi gọi là phép 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 hình chuông của các số ngẫu nhiên, numpy là cách tốt nhất để phân chia điều này.

VẬY, hãy gắn bó với một bộ tạo, nhưng hãy quyết định điều gì ngẫu nhiên bạn muốn - ngẫu nhiên, nhưng rõ ràng từ một đường cong phân phối, hoặc ngẫu nhiên như bạn có thể nhận được mà không cần thiết bị lượng tử.


Cảm ơn Paul rất nhiều, câu trả lời của bạn rất hữu ích! Tôi không tìm kiếm sự ngẫu nhiên của 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à đủ đối với tôi. Hóa ra là tôi không thể dính vào một trình tạo như tôi muốn vì tôi cần numpy cho 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.