Python 中配对列表的随机样本
Random sample of paired lists in Python
我有两个列表 x 和 y,长度都是 n,xi 和 yi 成对。我如何在保留配对信息的同时从这两个列表中随机抽取 m 值(例如 x[10] 和 y[10] 将在结果样本中在一起)
我的初步想法是这样的
- 使用 zip 创建元组列表
- 随机排列元组列表
- select 列表中的前 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 化吗?
如果你有两个列表,其中的元素是直接成对的,并且只是 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)]
如果您有两个相同维度的列表,您只想对这些元素的一个子集进行采样并将结果配对。
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 = [(x[n], y[n]) for n in idx]
>>> pairs
[(5, 10), (2, 7), (1, 6)]
您可以对 m 对进行采样,然后使用以下代码将它们分成两个列表:
import random
x = list(range(1, 10))
y = list("abcdefghij")
m = 3
x_sub, y_sub = zip(*random.sample(list(zip(x, y)), m))
您可以实施 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
and 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)
详情
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 了解更多工具。
我有两个列表 x 和 y,长度都是 n,xi 和 yi 成对。我如何在保留配对信息的同时从这两个列表中随机抽取 m 值(例如 x[10] 和 y[10] 将在结果样本中在一起)
我的初步想法是这样的
- 使用 zip 创建元组列表
- 随机排列元组列表
- select 列表中的前 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 化吗?
如果你有两个列表,其中的元素是直接成对的,并且只是 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)]
如果您有两个相同维度的列表,您只想对这些元素的一个子集进行采样并将结果配对。
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 = [(x[n], y[n]) for n in idx]
>>> pairs
[(5, 10), (2, 7), (1, 6)]
您可以对 m 对进行采样,然后使用以下代码将它们分成两个列表:
import random
x = list(range(1, 10))
y = list("abcdefghij")
m = 3
x_sub, y_sub = zip(*random.sample(list(zip(x, y)), m))
您可以实施 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
and 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)
详情
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 了解更多工具。