【问题标题】:Drawing 5 elements uniformly from a list of lists从列表列表中统一绘制 5 个元素
【发布时间】:2020-07-08 14:14:11
【问题描述】:

这里有一些背景,所以请耐心等待。

我有一个列表列表,称之为nested_lists,其中每个列表的格式为 [[1,2,3,...], [4,3,1,...]](即每个列表包含两个整数列表)。现在,在这些列表中的每一个中,两个整数列表具有相同的长度,并且对应于相同索引的两个整数表示 R^2 中的坐标。 例如,(1,4) 将是上例中的一个坐标。

现在,我的任务是从 nested_lists 中统一绘制 5 个唯一坐标(即每个坐标具有相同的被选中概率),无需替换。也就是说,从nested_lists中列表的所有坐标中,我试图统一绘制5个唯一坐标而不进行替换。

一种非常直接的方法是: 1. 在nested_lists 中创建所有唯一坐标的列表。 2、使用numpy.random.choice对5个元素进行均匀采样,无需替换。 代码是这样的:

import numpy as np
coordinates = []
#Get list of all unique coordinates
for list in nested_lists:
    
    l = len(list[0])
    for i in range(0, l):
        
        coordinate = (list[0][i], list[1][i])
        if coordinate not coordinates:
            coordinates += [coordinate]

draws = np.random.choice(coordinates, 5, replace=False, p= [1/len(coordinates)]*len(coordinates))

但是获取所有唯一坐标的集合在计算上可能非常昂贵,特别是如果nested_lists 包含数百万个列表,每个列表中都有数千个坐标。所以我正在寻找方法来执行相同的绘制,而不必先获取所有坐标的列表。

我想到的一种方法是从nested_lists 中的每个列表中使用加权概率进行抽样。 所以得到每个列表的大小(坐标数)的列表,然后遍历每个列表,绘制一个概率为(size/sum(size))*(1/sum(sizes))的坐标。重复该过程直到绘制 5 个唯一坐标,然后应该对应于我们想要绘制的内容。代码是这样的:

no_coordinates = lambda x: len(x[0])
sizes = list(map(no_coordinates, nested_lists))
i = 0
sum_sizes = sum(sizes)
draws = []
while i != 5:                           #to make sure we get 5 draws

    for list in nested_lists:
      
        size = len(list[0])
        p = size/(sum_sizes**2)
        for j in range(0, size):
            
            if i >= 5:                        exit for loop when we reach 5 draws
                break
            if np.random.random() < p and (list[0][j], list[1][j]) not in draws:
                draws += (list[0][j], list[1][j])
                i += 1
            
            

上面的代码似乎在计算上更高效,但我不确定它是否真的以与整体所需的概率相同的概率进行绘制。根据我的计算,总体概率为sum(size)/sum_sizes**2,这与1/sum_sizes(我们需要的概率)相同,但同样,我不确定这是否正确。

所以我想知道是否有更有效的方法来绘制我想要的,以及我的方法是否真的正确。

【问题讨论】:

  • 有多少个独特的位置?
  • 另外,是 R2 整数中的坐标,如果是,最大 int 值是多少?坐标是否应该在列表中具有相同的分布?
  • 不幸的是,唯一位置的数量是未知的(真实数据集)。它可以是 10-100k 唯一坐标范围内的任何位置。
  • R2 中的坐标是整数,但实际上并没有任何最大值/最小值。他们的价值观。分布也不应该相同。
  • 最大/分钟。必须事先找到。数据 atm 只是我描述的形式的原始坐标,没有提供太多关于它们的信息。

标签: python random


【解决方案1】:

您可以使用bootstrapping。基本上,这个想法是通过替换绘制一些大量(但固定)的坐标来估计每个坐标的概率。然后,您可以使用转换后的密度从此列表中进行二次采样。

from collections import Counter

bootstrap_sample_size = 1000
total_lists = len(nested_lists)
list_len = len(nested_lists[0])
# set will make more sense in this example
# I used counter to allow for future statistical manipulations
c = Counter()

for _ in range(bootstrap_sample_size):
    x, y = random.randrange(total_lists), random.randrange(list_len) 
    random_point = nested_lists[x][0][y], nested_lists[x][1][y]
    c.update((random_point,))

# now c contains counts for 1000 points with replacements
# let's just ignore these probabilities to get uniform sample
result = random.sample(c.keys(), 5)

这不会是完全统一的,但 bootstrap 提供了统计保证,即随着 bootstrap_sample_size 的增加,它将任意接近均匀分布。对于大多数实际应用来说,1000 个样本通常就足够了。

【讨论】:

  • 啊,我考虑过引导程序。我想这是一种可能比我的两种方法更有效的方法。
猜你喜欢
  • 2022-01-05
  • 2020-07-18
  • 1970-01-01
  • 1970-01-01
  • 2018-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多