2015-09-15 2 views
3

У меня есть два списка х и у, обе длины п с х я и у я, образуя пару. Как я мог принять случайную выборку м значений из этих двух списков, сохраняя при этом информацию о подключении (например, х [10] и у [10] будут вместе в полученном образце)случайной выборки из парных списков в Python

Моя первоначальная идея заключается в следующем.

  • использование почтового индекса, чтобы создать список кортежей
  • перетасовать список кортежей
  • выбрать первые м кортежей из списка
  • разбить кортежи в новые спаренных списки

И код будет выглядеть примерно так.

templist = list() 
for tup in zip(x, y): 
    templist.append(tup) 
random.shuffle(templist) 
x_sub = [a for a, b in templist[0:m]] 
y_sub = [b for a, b in templist[0:m]] 

Это кажется довольно клочковым для меня. Есть ли способ сделать это более ясным, кратким или питоническим?

+0

Вы посмотрели ['random.sample'] (https://docs.python.org/2/library/random.html#random.sample)? – metatoaster

+0

@metatoaster В качестве замены команды shuffle? Все решение будет по-прежнему немного клочья. Если 'random.sample' может принимать два парных списка в качестве входных данных. –

ответ

5

может быть, вы имеете в виду выборки м элементы

x_sub, y_sub = zip(*random.sample(list(zip(x, y)), m)) 
+0

Мне нравится, что это решение создает два новых списка, а не один список кортежей. Вид плотный в противном случае, но краткость и ясность всегда кажутся расходимыми! –

+0

У меня ошибка при попытке выполнить это (при условии, что m = 3) – Alexander

+0

@Alexander 'm' - это размер выборки, OP не предоставил ему просто переменную' m', какая ошибка - отлично работает для меня. – AChampion

0

Если у вас есть два списка с элементами, которые являются прямыми парами друг друга и просто zip их (и в Python 3, гипсе, что объект в list), а затем использовать random.sample взять пробу.

>>> m = 4 
>>> x = list(range(0, 3000, 3)) 
>>> y = list(range(0, 2000, 2)) 
>>> random.sample(list(zip(x, y)), m) 
[(2145, 1430), (2961, 1974), (9, 6), (1767, 1178)] 
0

Если у вас есть два списка одинаковых размеров, вы просто хотите попробовать подмножество этих элементов и соединить результаты.

x = [1,2,3,4,5] 
y = [6,7,8,9,10] 
sample_size = 3 
idx = np.random.choice(len(x), size=sample_size, replace=False) 
pairs = zip([x[n], y[n]) for n in idx] 
>>> pairs 
[(5, 10), (2, 7), (1, 6)] 
0

Вы можете реализовать рецепт random_product itertools. Я буду использовать стороннюю библиотеку, more_itertools, которая реализует этот рецепт для нас. Установите эту библиотеку через pip install more_itertools.

Код

import more_itertool as mit 


x, y, m = "abcdefgh", range(10), 2 

iterable = mit.random_product(x, y, repeat=m) 

Результаты

iterable 
# ('e', 9, 'f', 3) 

Не ясно, в какой форме OP хочет результатов, но вы можете сгруппировать x и y вместе, например, [(x[0], y[0]), (x[1], y[1]), ...]:

paired_xy = list(zip(*[iter(iterable)]*2)) 
paired_xy 
# [('e', 9), ('f', 3)] 

Смотрите также more_itertools.sliced и more_itertools.grouper для группировки последовательных элементов.

Кроме того, вы можете zip далее по группе x и y, например. [(x[0], x[1], ...), (y[0], y[1], ...)]:

paired_xx = list(zip(*paired_xy)) 
paired_xx 
# [('e', 'f'), (9, 3)] 

Обратите внимание, этот подход принимает любое количество итерируемыми, x, y, z и т.д.

# Select m random items from multiples iterables, REF 101 
x, y, m = "abcdefgh", range(10), 2 
a, b, c = "ABCDE", range(10, 100, 10), [False, True] 
iterable = mit.random_product(x, y, a, b, c, repeat=m) 
iterable 
# ('d', 6, 'E', 80, True, 'a', 1, 'D', 50, False) 

Детали

Из itertools recipes:

def random_product(*args, repeat=1): 
    "Random selection from itertools.product(*args, **kwds)" 
    pools = [tuple(pool) for pool in args] * repeat 
    return tuple(random.choice(pool) for pool in pools) 

Мы можем видеть, что функция действительно принимает несколько аргументов, каждая из которых становится коллекцией пулов. Размер пула масштабируется на значение repeat ключевое слово. Случайный выбор производится из каждого пула и объединяется в качестве конечного результата.

См. Также more_itertools docs для получения дополнительных инструментов.

Смежные вопросы