Python中配对列表的随机样本

时间:2015-09-15 02:47:59

标签: python random-sample

我有两个列表 x y ,长度 n x i y i 形成一对。我如何从这两个列表中随机抽取 m 值,同时保留配对信息(例如x [10]和y [10]将在最终样本中合在一起)

我最初的想法就是这个。

  • 使用zip创建元组列表
  • 随机播放元组列表
  • 从列表中选择第一个 m 元组
  • 将元组分解为新的配对列表

代码看起来像这样。

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]]

这对我来说似乎很狡猾。有什么方法可以让我更清楚,更简洁,还是Pythonic?

4 个答案:

答案 0 :(得分:7)

也许你的意思是采样m个元素

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

答案 1 :(得分: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)]

答案 2 :(得分: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)]

答案 3 :(得分: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希望以何种形式获得结果,但您可以将xy组合在一起,例如[(x[0], y[0]), (x[1], y[1]), ...]

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

另请参阅more_itertools.slicedmore_itertools.grouper,以便对连续项目进行分组。

或者,您可以zip进一步分组到xy,例如[(x[0], x[1], ...), (y[0], y[1], ...)]

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

注意,此方法接受任意数量的可迭代,xyz等。

# 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