Numpy: รับชุดสุ่มแถวจากอาร์เรย์ 2 มิติ


160

ฉันมีอาร์เรย์ 2 มิติที่มีขนาดใหญ่มากซึ่งมีลักษณะดังนี้:

a=
[[a1, b1, c1],
 [a2, b2, c2],
 ...,
 [an, bn, cn]]

การใช้ numpy มีวิธีง่าย ๆ ในการรับอาร์เรย์ 2D ใหม่ด้วยเช่น 2 แถวสุ่มจากอาร์เรย์เริ่มต้นa(โดยไม่มีการแทนที่)?

เช่น

b=
[[a4,  b4,  c4],
 [a99, b99, c99]]

8
มันโง่ที่จะมีคำถามหนึ่งคำถามเพื่อทดแทนและคำถามที่ไม่มีคุณควรอนุญาตให้ทั้งคำตอบและที่จริงแล้วสนับสนุนทั้งสองคำตอบ
Pinocchio

คำตอบ:


195
>>> A = np.random.randint(5, size=(10,3))
>>> A
array([[1, 3, 0],
       [3, 2, 0],
       [0, 2, 1],
       [1, 1, 4],
       [3, 2, 2],
       [0, 1, 0],
       [1, 3, 1],
       [0, 4, 1],
       [2, 4, 2],
       [3, 3, 1]])
>>> idx = np.random.randint(10, size=2)
>>> idx
array([7, 6])
>>> A[idx,:]
array([[0, 4, 1],
       [1, 3, 1]])

นำมารวมกันเป็นกรณีทั่วไป:

A[np.random.randint(A.shape[0], size=2), :]

สำหรับการทดแทนที่ไม่ใช่ (จำนวน 1.7.0+):

A[np.random.choice(A.shape[0], 2, replace=False), :]

ฉันไม่เชื่อว่ามีวิธีที่ดีในการสร้างรายการแบบสุ่มโดยไม่ต้องเปลี่ยนก่อน 1.7 บางทีคุณสามารถตั้งค่าคำจำกัดความเล็ก ๆ ที่รับรองว่าค่าทั้งสองนั้นไม่เหมือนกัน


4
อาจจะไม่ใช่วิธีที่ดี แต่เป็นวิธีที่ดีเท่าnp.random.choiceและนั่นก็คือnp.random.permutation(A.shape[0])[:2]มันไม่ดี แต่np.random.choiceในเวลานี้คือ ... หรือถ้าคุณไม่สนใจที่จะเปลี่ยนอาเรย์ของคุณ - สถานที่,np.random.shuffle
seberg

1
ก่อนที่จะมีจำนวน 1.7 ใช้สุ่ม.ตัวอย่าง (xrange (10), 2)
ปฏิเสธ

3
ทำไมคุณถึงตั้งชื่อตัวแปร A และ B และสิ่งของ? มันทำให้อ่านยากขึ้น
Pinocchio

48

นี่คือโพสต์เก่า แต่นี่คือสิ่งที่ดีที่สุดสำหรับฉัน:

A[np.random.choice(A.shape[0], num_rows_2_sample, replace=False)]

เปลี่ยน replace = False เป็น True เพื่อให้ได้สิ่งเดียวกัน แต่เปลี่ยนได้


2
@SalvadorDali ฉันได้แก้ไขโพสต์ของ Hezi เพื่อไม่เลือกแทนที่ เมื่อแก้ไขเป็น peer-reviewed คุณจะเห็นเพิ่มพระรามไปreplace=False choice
0x24a537r9

8
@ 0x24a537r9 คุณไม่ควรทำเช่นนี้ นี่คือคำตอบของเขาและคุณเปลี่ยนมัน ถ้าคุณต้องการ - เพิ่มคำตอบของคุณและอย่าเปลี่ยนคำตอบของคนอื่นที่เปลี่ยนคำตอบอย่างมีนัยสำคัญ
ซัลวาดอร์ดาลี

@SalvadorDali ทำไมไม่
สกอตต์

25

อีกทางเลือกหนึ่งคือการสร้างมาสก์แบบสุ่มหากคุณต้องการเก็บตัวอย่างข้อมูลของคุณด้วยปัจจัยบางอย่าง สมมติว่าฉันต้องการตัวอย่างลดลงเหลือ 25% ของชุดข้อมูลดั้งเดิมของฉันซึ่งปัจจุบันอยู่ในอาร์เรย์data_arr:

# generate random boolean mask the length of data
# use p 0.75 for False and 0.25 for True
mask = numpy.random.choice([False, True], len(data_arr), p=[0.75, 0.25])

ตอนนี้คุณสามารถโทรหาdata_arr[mask]และส่งคืนแถวที่ 25 ~ สุ่มตัวอย่างแบบสุ่ม


คุณอาจต้องการเพิ่มreplace = Falseถ้าคุณไม่ต้องการสุ่มตัวอย่างด้วยการแทนที่
ซาร่าห์

10

นี่เป็นคำตอบที่คล้ายกับที่ Hezi Rasheff จัดไว้ให้ แต่ผู้ใช้งานงูใหญ่รุ่นใหม่เข้าใจว่าเกิดอะไรขึ้น (ฉันสังเกตเห็นว่านักเรียน datascience ใหม่จำนวนมากดึงตัวอย่างแบบสุ่มในวิธีที่แปลกประหลาดเพราะพวกเขาไม่รู้ว่ากำลังทำอะไรอยู่ในหลาม)

คุณสามารถรับดัชนีสุ่มจำนวนมากจากอาร์เรย์ของคุณโดยใช้:

indices = np.random.choice(A.shape[0], amount_of_samples, replace=False)

จากนั้นคุณสามารถใช้การแบ่งส่วนกับอาร์เรย์ numpy ของคุณเพื่อรับตัวอย่างที่ดัชนีเหล่านั้น:

A[indices]

สิ่งนี้จะทำให้คุณได้จำนวนตัวอย่างที่สุ่มจากข้อมูลของคุณ


5

ฉันเห็นการเปลี่ยนแปลงได้รับการแนะนำ ในความเป็นจริงมันสามารถทำให้เป็นหนึ่งบรรทัด:

>>> A = np.random.randint(5, size=(10,3))
>>> np.random.permutation(A)[:2]

array([[0, 3, 0],
       [3, 1, 2]])

4

หากคุณต้องการแถวเดียวกัน แต่เป็นเพียงกลุ่มตัวอย่างแบบสุ่ม

import random
new_array = random.sample(old_array,x)

ที่นี่ x ต้องเป็น 'int' เพื่อกำหนดจำนวนแถวที่คุณต้องการสุ่มเลือก


4
ใช้งานได้เฉพาะในกรณีที่ old_arrayเป็นลำดับหรือชุดไม่ใช่อาเรย์ numpy [link] ( docs.python.org/3/library/random.html#functions-for-sequences )
leermeester

2

หากคุณต้องการสร้างแถวย่อยหลายชุดแบบสุ่มตัวอย่างเช่นหากคุณทำ RANSAC

num_pop = 10
num_samples = 2
pop_in_sample = 3
rows_to_sample = np.random.random([num_pop, 5])
random_numbers = np.random.random([num_samples, num_pop])
samples = np.argsort(random_numbers, axis=1)[:, :pop_in_sample]
# will be shape [num_samples, pop_in_sample, 5]
row_subsets = rows_to_sample[samples, :]
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.