简体   繁体   English

从多个列表中随机创建“n”个组合

[英]Creating 'n' combinations randomly from multiple lists

def models():
    default = [0.6,0.67,2.4e-2,1e-2,2e-5,1.2e-3,2e-5]
    lower = [np.log10(i/10) for i in default]
    upper = [np.log10(i*10) for i in default]
    n = 5
    a = np.logspace(lower[0],upper[0],n)
    b = np.logspace(lower[1],upper[1],n)
    c = np.logspace(lower[2],upper[2],n)
    d = np.logspace(lower[3],upper[3],n)
    e = np.logspace(lower[4],upper[4],n)
    f = np.logspace(lower[5],upper[5],n)
    g = np.logspace(lower[6],upper[6],n)

    combs = itertools.product(a,b,c,d,e,f,g)

    list1 = []

    for x in combs:
        x = list(x)
        list1.append(x)


    return list1

The code above returns a list of 5^7 = 78,125 lists.上面的代码返回一个包含 5^7 = 78,125 个列表的列表。 Is there a way I can combine items in a,b,c,d,e,f,g, possibly randomly, to create a list of say, 10000, lists?有没有一种方法可以组合 a、b、c、d、e、f、g 中的项目,可能是随机的,以创建一个包含 10000 个列表的列表?

You could take random samples of each array and combine them, especially if you don't need to guarantee that specific combinations don't occur more than once:您可以对每个数组进行随机采样并将它们组合起来,特别是如果您不需要保证特定组合不会发生多次:

import numpy as np
import random


def random_models(num_values):
    n = 5
    default = [0.6, 0.67, 2.4e-2, 1e-2, 2e-5, 1.2e-3, 2e-5]
    ranges = zip((np.log10(i/10) for i in default),
                 (np.log10(i*10) for i in default))

    data_arrays = []
    for lower, upper in ranges:
        data_arrays.append(np.logspace(lower, upper, n))

    results = []

    for i in xrange(num_values):
        results.append([random.choice(arr) for arr in data_arrays])

    return results


l = random_models(10000)
print len(l)

Here's a version that will avoid repeats up until you request more data than can be given without repeating:这是一个避免重复的版本,直到您请求的数据多于无需重复即可提供的数据:

def random_models_avoid_repeats(num_values):
    n = 5
    default = [0.6, 0.67, 2.4e-2, 1e-2, 2e-5, 1.2e-3, 2e-5]

    # Build the range data (tuples of (lower, upper) range)
    ranges = zip((np.log10(i/10) for i in default),
                 (np.log10(i*10) for i in default))

    # Create the data arrays to sample from
    data_arrays = []
    for lower, upper in ranges:
        data_arrays.append(np.logspace(lower, upper, n))

    sequence_data = []
    for entry in itertools.product(*data_arrays):
        sequence_data.append(entry)

    results = []

    # Holds the current choices to choose from.  The data will come from
    # sequence_data above, but randomly shuffled.  Values are popped off the
    # end to keep things efficient.  It's possible to ask for more data than
    # the samples can give without repeats.  In that case, we'll reload
    # temp_data, randomly shuffle again, and start the process over until we've
    # delivered the number of desired results.
    temp_data = []
    # Build the lists
    for i in xrange(num_values):
        if len(temp_data) == 0:
            temp_data = sequence_data[:]
            random.shuffle(temp_data)
        results.append(temp_data.pop())

    return results

Also note that we can avoid building a results list if you make this a generator by using yield .另请注意,如果您使用yield其设为生成器,我们可以避免构建结果列表。 However, you'd want to consume the results using a for statement as well:但是,您还想使用for语句来使用结果:

def random_models_avoid_repeats_generator(num_values):
    n = 5
    default = [0.6, 0.67, 2.4e-2, 1e-2, 2e-5, 1.2e-3, 2e-5]

    # Build the range data (tuples of (lower, upper) range)
    ranges = zip((np.log10(i/10) for i in default),
                 (np.log10(i*10) for i in default))

    # Create the data arrays to sample from
    data_arrays = []
    for lower, upper in ranges:
        data_arrays.append(np.logspace(lower, upper, n))

    sequence_data = []
    for entry in itertools.product(*data_arrays):
        sequence_data.append(entry)

    # Holds the current choices to choose from.  The data will come from
    # sequence_data above, but randomly shuffled.  Values are popped off the
    # end to keep things efficient.  It's possible to ask for more data than
    # the samples can give without repeats.  In that case, we'll reload
    # temp_data, randomly shuffle again, and start the process over until we've
    # delivered the number of desired results.
    temp_data = []
    # Build the lists
    for i in xrange(num_values):
        if len(temp_data) == 0:
            temp_data = sequence_data[:]
            random.shuffle(temp_data)
        yield temp_data.pop()

You'd have to use it like this:你必须像这样使用它:

for entry in random_models_avoid_repeats_generator(10000):
    # Do stuff...

Or manually iterate over it using next() .或者使用next()手动迭代它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM