Nhất quán tạo cùng một mảng numpy ngẫu nhiên


89

Tôi đang đợi một nhà phát triển khác hoàn thành một đoạn mã sẽ trả về một mảng hình dạng np (100,2000) với các giá trị là -1,0 hoặc 1.

Trong thời gian chờ đợi, tôi muốn tạo ngẫu nhiên một mảng có các đặc điểm giống nhau để tôi có thể bắt đầu quá trình phát triển và thử nghiệm của mình. Vấn đề là tôi muốn mảng được tạo ngẫu nhiên này giống nhau mỗi lần, để tôi không thử nghiệm với một mảng luôn thay đổi giá trị của nó mỗi khi tôi chạy lại quy trình của mình.

Tôi có thể tạo mảng của mình như thế này, nhưng có cách nào để tạo nó sao cho mỗi lần như vậy không. Tôi có thể nhặt đồ vật và bỏ chọn nó, nhưng tự hỏi liệu có cách nào khác không.

r = np.random.randint(3, size=(100, 2000)) - 1

Câu trả lời:


84

Đơn giản chỉ cần bắt đầu tạo số ngẫu nhiên với một giá trị cố định, ví dụ:

numpy.random.seed(42)

Bằng cách này, bạn sẽ luôn nhận được cùng một dãy số ngẫu nhiên.


43
Ai đó đã lẻn vào numpy.random.seed()chức năng khi tôi không chú ý. :-) Tôi cố tình để nó ra khỏi mô-đun ban đầu. Tôi khuyên mọi người nên sử dụng các phiên bản của riêng họ RandomStatevà chuyển các đối tượng đó xung quanh.
Robert Kern

6
Robert là một người đóng góp lớn cho numpy. Tôi nghĩ chúng ta nên đưa ra ý kiến ​​của anh ấy có trọng lượng.
không được dùng vào

10
@deprecated: Tôi rất biết ơn công việc của Robert, nhưng công việc của anh ấy không thể thay thế cho việc đưa ra cơ sở lý luận cho đề xuất. Hơn nữa, nếu việc sử dụng numpy.random.seed()không được khuyến khích, điều này nên được đề cập trong tài liệu . Rõ ràng, những người đóng góp khác cho NumPy không chia sẻ ý kiến ​​của Robert. Không có ý định xúc phạm nào cả, tôi chỉ tò mò.
Sven Marnach

13
Điều này giống như sử dụng random.seedso với sử dụng một random.Randomđối tượng trong thư viện chuẩn Python. Nếu bạn sử dụng random.seedhoặc numpy.random.seed, bạn đang gieo tất cả các trường hợp ngẫu nhiên, cả trong mã của bạn và trong bất kỳ mã nào bạn đang gọi hoặc bất kỳ mã nào được chạy trong cùng một phiên với của bạn. Nếu những thứ đó phụ thuộc vào những thứ đó thực sự là ngẫu nhiên, thì bạn bắt đầu gặp vấn đề. Nếu bạn triển khai mã đặt hạt giống ngẫu nhiên, bạn có thể tạo ra lỗ hổng bảo mật.
asmeurer

3
@asmeurer Bất kỳ ai sử dụng trình tạo số giả cho mục đích bảo mật có thể không biết họ đang làm gì.
JAB

191

Tạo phiên bản của riêng numpy.random.RandomState()bạn với hạt giống bạn đã chọn. Không sử dụng numpy.random.seed()ngoại trừ để làm việc xung quanh các thư viện không linh hoạt không cho phép bạn vượt qua RandomStatephiên bản của riêng bạn .

[~]
|1> from numpy.random import RandomState

[~]
|2> prng = RandomState(1234567890)

[~]
|3> prng.randint(-1, 2, size=10)
array([ 1,  1, -1,  0,  0, -1,  1,  0, -1, -1])

[~]
|4> prng2 = RandomState(1234567890)

[~]
|5> prng2.randint(-1, 2, size=10)
array([ 1,  1, -1,  0,  0, -1,  1,  0, -1, -1])

7
Bạn có bất kỳ lý do hợp lý cho đề xuất của bạn? Có gì sai với numpy.random.seed()? Tôi biết nó không an toàn bằng sợi chỉ, nhưng nó thực sự tiện lợi nếu bạn không cần an toàn cho sợi.
Sven Marnach

52
Nó chủ yếu là để hình thành thói quen tốt. Bạn có thể không cần các luồng độc lập ngay bây giờ, nhưng Sven-6 tháng-kể từ bây giờ thì có thể. Nếu bạn viết thư viện của mình để sử dụng các phương pháp trực tiếp từ đó numpy.random, bạn không thể tạo các luồng độc lập sau này. Việc viết thư viện với mục đích kiểm soát các luồng PRNG cũng dễ dàng hơn. Luôn có nhiều cách để vào thư viện của bạn và mỗi cách trong số chúng phải có một cách để kiểm soát hạt giống. Đi vòng quanh các đối tượng PRNG là một cách làm rõ ràng hơn là dựa vào numpy.random.seed(). Thật không may, hộp nhận xét này quá ngắn để chứa thêm ví dụ. :-)
Robert Kern

25
Một cách khác để mô tả cơ sở lý luận của Robert: sử dụng numpy.random.seed sử dụng một biến toàn cục để giữ trạng thái PRNG và các lý do tiêu chuẩn tương tự khiến các biến toàn cục không tốt được áp dụng ở đây.
Robie Basak

9
Nếu bạn muốn PRNG độc lập, đừng gieo mầm cho họ bất cứ thứ gì. Chỉ sử dụng numpy.random.RandomState()mà không có đối số. Điều này sẽ tạo ra trạng thái với các giá trị duy nhất được rút ra từ các cơ sở hệ điều hành của bạn cho những thứ như vậy ( /dev/urandomtrên máy UNIX và Windows tương đương ở đó). Nếu numpy.random.RandomState(1234567890)không hiệu quả với bạn, vui lòng hiển thị chính xác những gì bạn đã nhập và chính xác thông báo lỗi mà bạn nhận được.
Robert Kern

5
Không phải là một ý tưởng tốt. Sử dụng numpy.random.RandomState()không có đối số để có kết quả tốt nhất.
Robert Kern

3

Nếu bạn đang sử dụng các hàm khác dựa trên trạng thái ngẫu nhiên, bạn không thể chỉ đặt và hạt giống tổng thể, mà thay vào đó nên tạo một hàm để tạo danh sách số ngẫu nhiên của bạn và đặt hạt giống làm tham số của hàm. Điều này sẽ không làm phiền bất kỳ trình tạo ngẫu nhiên nào khác trong mã:

# Random states
def get_states(random_state, low, high, size):
    rs = np.random.RandomState(random_state)
    states = rs.randint(low=low, high=high, size=size)
    return states

# Call function
states = get_states(random_state=42, low=2, high=28347, size=25)

3

Điều quan trọng là phải hiểu hạt giống của trình tạo ngẫu nhiên là gì và khi nào / cách nó được đặt trong mã của bạn (ví dụ: kiểm tra ở đây để có giải thích tốt về ý nghĩa toán học của hạt giống).

Đối với điều đó, bạn cần thiết lập hạt giống bằng cách thực hiện:

random_state = np.random.RandomState(seed=your_favorite_seed_value)

Sau đó, điều quan trọng là tạo các số ngẫu nhiên từ random_state chứ không phải từ np.random. Tức là bạn nên làm:

random_state.randint(...)

thay vì

np.random.randint(...) 

sẽ tạo một phiên bản mới của RandomState () và về cơ bản sử dụng đồng hồ bên trong máy tính của bạn để đặt hạt giống.


2

Tôi chỉ muốn làm rõ điều gì đó liên quan đến câu trả lời của @Robert Kern trong trường hợp điều đó không rõ ràng. Ngay cả khi bạn sử dụng, RandomStatebạn sẽ phải khởi tạo nó mỗi khi bạn gọi một phương thức ngẫu nhiên numpy như trong ví dụ của Robert, nếu không bạn sẽ nhận được các kết quả sau.

Python 3.6.9 |Anaconda, Inc.| (default, Jul 30 2019, 19:07:31) 
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> prng = np.random.RandomState(2019)
>>> prng.randint(-1, 2, size=10)
array([-1,  1,  0, -1,  1,  1, -1,  0, -1,  1])
>>> prng.randint(-1, 2, size=10)
array([-1, -1, -1,  0, -1, -1,  1,  0, -1, -1])
>>> prng.randint(-1, 2, size=10)
array([ 0, -1, -1,  0,  1,  1, -1,  1, -1,  1])
>>> prng.randint(-1, 2, size=10)
array([ 1,  1,  0,  0,  0, -1,  1,  1,  0, -1])
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.