Numpy взять много образцов без замены строк - PullRequest
0 голосов
/ 22 декабря 2018

У меня действительно большой список.Представьте, что это выглядит примерно так:

test = ['llama', 'cow', 'horse', 'fish', 'sheep', 'goat', 'cat', 'dog']

Я хочу выбрать из этого списка много раз.Я хочу, чтобы каждый образец был взят без замены.В этом случае я хочу избегать циклов for.

Я видел много решений в StackOverflow, которые близки, но не совсем то, что мне нужно здесь.Скажем, каждый образец, который мне нужен, должен был иметь размер 3. Если бы я хотел сделать выборку с заменой, это сработало бы:

np.random.choice(test, size=(100, 3))

Это дало бы мне 100 строк с выборкой по 3 в каждой строке.Проблема в том, что в каждой конкретной строке могут быть повторы, и я не могу попросить ее сделать выборку без замены, потому что 300 > len(test).

Есть ли способ обойти это, который поддерживает случайность?Я видел потенциальные решения, использующие np.argsort, но я не уверен, что они все еще на самом деле случайные, учитывая, что сортировка уже выполнена.

Ответы [ 3 ]

0 голосов
/ 22 декабря 2018

Для этого можно использовать random.sample, из документации :

Возвращать список длины уникальных элементов, выбранных из последовательности совокупности.Используется для случайной выборки без замены.

И повторите процесс n_times с использованием списка:

n_times = 100
n_sample = 3
[random.sample(test, n_sample) for i in range(n_times)]

[['llama', 'goat', 'sheep'],
 ['cat', 'horse', 'dog'],
 ['sheep', 'dog', 'goat'],
 ['cat', 'cow', 'llama'],
 ['dog', 'fish', 'horse'],
 ['llama', 'horse', 'cow'],
 ['dog', 'goat', 'cow'],
 ['llama', 'cow', 'sheep'],
 ['fish', 'dog', 'horse'],
 ... 
0 голосов
/ 22 декабря 2018

Вот векторизованный подход с rand+argsort/argpartition трюком из here -

idx = np.random.rand(100, len(test)).argpartition(3,axis=1)[:,:3]
out = np.take(test, idx)

Давайте проверим, что все уникальны в строке с помощью некоторых панд -

In [51]: idx = np.random.rand(100, len(test)).argpartition(3,axis=1)[:,:3]
    ...: out = np.take(test, idx)

In [52]: import pandas as pd

In [53]: (pd.DataFrame(out).nunique(axis=1).values==3).all()
Out[53]: True
0 голосов
/ 22 декабря 2018

Вы можете запустить np.random.choice без замены один раз для каждой строки и поместить результаты в матрицу.Это можно сделать с помощью этой команды.

np.array([np.random.choice(test, 3, replace=False) for i in range(100)])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...