如何从 Python 3 生成器中检索随机元素?
How to retrieve random elements from a Python 3 generator?
有人建议 this 生成组合:这会给我组合,但是不会有 [=36= 中提到的所需属性(需要 post 处理) ]end 我的问题。
请理解,len(myList) = 10e6
并且需要更大的组合。
我正在处理图表。
假设我有一个非常大的列表。我正在使用 itertools 为此列表生成 组合。我想要实现的是随机 select 元素,而不具体化生成器(即使对于 16 GB 的 RAM,它也太大了,我学到了困难的方法 ) .
这是我到目前为止所做的:
import itertools
import random
myList = [('abc',1), ('bcd',2), ('cdef',3), ('adcv',4), ('zofd',5), ('qmkdf',6), ('qmk',7), ('oswd',8)]
# actual list is much larger than above in my case
myCombi_gen = itertools.combinations(myList, r=2)
# Above should generate: [(('abc',1), ('bcd',2)), (('abc',1), ('cdef',3)), .....]
N = 15
counter = 0
for elem in myCombi_gen:
if random.random() > 0.5: # selecting based on probability
print(elem, end=' ')
counter+=1
# doing something useful here
if counter == N:
break
我的问题是,最终 selected 的组合中的元素 集中在一个地方 。我希望它们更均匀地分布(可能是某种分布?)。一些提醒会有所帮助。
备注:
即使没有概率 selection,我也只需要一小部分组合。如果不使用随机化的 selection,那将简单地获取第一个 N 个元素。代码已相应更新。
为清楚起见,对于我的具体情况,我不能执行以下操作:
# Cannot do the following, memory (RAM) usage blows up
all_combi = list(itertools.combinations(myList, r=2))
random.shuffle(all_combi)
selected_combi = random.sample(all_combi, N)
许多人建议的一种常见方法似乎是,为什么不采样 myList
然后生成组合?不,我已经更新了 myList 的结构以便更好地理解。它已排序并且必须保持排序。 itertools.combinations
生成适合我目的的排序组合,这就是我使用它的原因(我对任何其他组合生成器持开放态度)。我希望对组合执行采样,而不是对 myList
.
的原始元素执行采样
# This approach is unacceptably slow (though I didn't time it):
# making random combinations of size 2
selected = set()
while True:
left = random.choice(myList)
right = random.choice(myList)
if left[1] < right[1] and left[0] != right[0] and (left, right) not in selected and (right, left) not in selected:
selected.add((left, right))
if len(selected) == N:
break
这应该有助于解决本地化问题。
import random
N = 15
counter = 0
# List of data
myList = [['abc', 'bcd', 'cdef', 'adcv', 'zofd', 'qmkdf', 'qmk', 'oswd'],
['zbc', 'zcd', 'zdef', 'zdcv', 'zofd', 'zmkdf', 'zmk', 'zswd'],
['ahhc', 'gcd', 'fdef', 'fdcv', 'gofd', 'gmkdf', 'gmk', 'gswd']]
num_lists = 2
while counter < 15:
# Randomly select n lists
sampled_lists_index = random.sample(list(range(len(myList))), num_lists)
for i in sampled_lists_index:
# print(i)
print(random.sample(myList[i], 1)[0], end=" ")
# Taking care of the formatting
print("\n")
counter += 1
使用more_itertools
。 1M排列,不到1分钟。
random_combination
:
Return a random r length subsequence of the elements in iterable.
This equivalent to taking a random selection from
itertools.combinations(iterable, r)
.
from more_itertools import random_combination, random_permutation
import string
s = string.ascii_letters
g = {tuple(random_permutation(s)) for i in range(1000000)}
result = set()
while len(result) != 15:
if (c := random_combination(g, r=2)) not in result: result.add(c)
具体问题:
from more_itertools import random_combinations as rc
N = 15
myList = [('abc',1), ('bcd',2), ('cdef',3), ('adcv',4), ('zofd',5), ('qmkdf',6), ('qmk',7), ('oswd',8)]
result = set()
while len(result) != N:
c = rc(myList, r=2)
if c not in result:
result.add(c)
这将产生以下结果:
{(('qmkdf', 6), ('qmk', 7)), (('cdef', 3), ('zofd', 5)), (('adcv', 4), ('zofd', 5)), (('bcd', 2), ('cdef', 3)), (('bcd', 2), ('qmk', 7)), (('adcv', 4), ('qmk', 7)), (('bcd', 2), ('adcv', 4)), (('abc', 1), ('zofd', 5)), (('abc', 1), ('oswd', 8)), (('cdef', 3), ('oswd', 8)), (('adcv', 4), ('qmkdf', 6)), (('cdef', 3), ('qmkdf', 6)), (('bcd', 2), ('oswd', 8)), (('abc', 1), ('qmkdf', 6)), (('bcd', 2), ('qmkdf', 6))}
请注意,组合是随机的,但要遵循排序顺序。
有人建议 this 生成组合:这会给我组合,但是不会有 [=36= 中提到的所需属性(需要 post 处理) ]end 我的问题。
请理解,len(myList) = 10e6
并且需要更大的组合。
我正在处理图表。
假设我有一个非常大的列表。我正在使用 itertools 为此列表生成 组合。我想要实现的是随机 select 元素,而不具体化生成器(即使对于 16 GB 的 RAM,它也太大了,我学到了困难的方法 ) .
这是我到目前为止所做的:
import itertools
import random
myList = [('abc',1), ('bcd',2), ('cdef',3), ('adcv',4), ('zofd',5), ('qmkdf',6), ('qmk',7), ('oswd',8)]
# actual list is much larger than above in my case
myCombi_gen = itertools.combinations(myList, r=2)
# Above should generate: [(('abc',1), ('bcd',2)), (('abc',1), ('cdef',3)), .....]
N = 15
counter = 0
for elem in myCombi_gen:
if random.random() > 0.5: # selecting based on probability
print(elem, end=' ')
counter+=1
# doing something useful here
if counter == N:
break
我的问题是,最终 selected 的组合中的元素 集中在一个地方 。我希望它们更均匀地分布(可能是某种分布?)。一些提醒会有所帮助。
备注:
即使没有概率 selection,我也只需要一小部分组合。如果不使用随机化的 selection,那将简单地获取第一个 N 个元素。代码已相应更新。
为清楚起见,对于我的具体情况,我不能执行以下操作:
# Cannot do the following, memory (RAM) usage blows up
all_combi = list(itertools.combinations(myList, r=2))
random.shuffle(all_combi)
selected_combi = random.sample(all_combi, N)
许多人建议的一种常见方法似乎是,为什么不采样 myList
然后生成组合?不,我已经更新了 myList 的结构以便更好地理解。它已排序并且必须保持排序。 itertools.combinations
生成适合我目的的排序组合,这就是我使用它的原因(我对任何其他组合生成器持开放态度)。我希望对组合执行采样,而不是对 myList
.
# This approach is unacceptably slow (though I didn't time it):
# making random combinations of size 2
selected = set()
while True:
left = random.choice(myList)
right = random.choice(myList)
if left[1] < right[1] and left[0] != right[0] and (left, right) not in selected and (right, left) not in selected:
selected.add((left, right))
if len(selected) == N:
break
这应该有助于解决本地化问题。
import random
N = 15
counter = 0
# List of data
myList = [['abc', 'bcd', 'cdef', 'adcv', 'zofd', 'qmkdf', 'qmk', 'oswd'],
['zbc', 'zcd', 'zdef', 'zdcv', 'zofd', 'zmkdf', 'zmk', 'zswd'],
['ahhc', 'gcd', 'fdef', 'fdcv', 'gofd', 'gmkdf', 'gmk', 'gswd']]
num_lists = 2
while counter < 15:
# Randomly select n lists
sampled_lists_index = random.sample(list(range(len(myList))), num_lists)
for i in sampled_lists_index:
# print(i)
print(random.sample(myList[i], 1)[0], end=" ")
# Taking care of the formatting
print("\n")
counter += 1
使用more_itertools
。 1M排列,不到1分钟。
random_combination
:
Return a random r length subsequence of the elements in iterable. This equivalent to taking a random selection from
itertools.combinations(iterable, r)
.
from more_itertools import random_combination, random_permutation
import string
s = string.ascii_letters
g = {tuple(random_permutation(s)) for i in range(1000000)}
result = set()
while len(result) != 15:
if (c := random_combination(g, r=2)) not in result: result.add(c)
具体问题:
from more_itertools import random_combinations as rc
N = 15
myList = [('abc',1), ('bcd',2), ('cdef',3), ('adcv',4), ('zofd',5), ('qmkdf',6), ('qmk',7), ('oswd',8)]
result = set()
while len(result) != N:
c = rc(myList, r=2)
if c not in result:
result.add(c)
这将产生以下结果:
{(('qmkdf', 6), ('qmk', 7)), (('cdef', 3), ('zofd', 5)), (('adcv', 4), ('zofd', 5)), (('bcd', 2), ('cdef', 3)), (('bcd', 2), ('qmk', 7)), (('adcv', 4), ('qmk', 7)), (('bcd', 2), ('adcv', 4)), (('abc', 1), ('zofd', 5)), (('abc', 1), ('oswd', 8)), (('cdef', 3), ('oswd', 8)), (('adcv', 4), ('qmkdf', 6)), (('cdef', 3), ('qmkdf', 6)), (('bcd', 2), ('oswd', 8)), (('abc', 1), ('qmkdf', 6)), (('bcd', 2), ('qmkdf', 6))}
请注意,组合是随机的,但要遵循排序顺序。