【问题标题】:Invert the random choice of keys in a numpy array反转numpy数组中键的随机选择
【发布时间】:2014-05-22 13:36:44
【问题描述】:

我有一个名为 arr 的巨大 np.array 有 N 个值,并通过以下方式随机选择其中 10% 的值:

choice=random.sample(range(N), int(N*percent))  # percent has values 0-1
newarr=arr[choice]

N 可能超过 200 万个值。

实际上我还需要一个包含其他 90% 值的数组。所以目前我使用以下非常慢的:

def buildRevChoice(choice, nevents):
        revChoice=[]
        for i in range(N):
            if not i in choice:
                revChoice.append(i)
        return revChoice

你能想出一种方法来固定它吗?

【问题讨论】:

  • 快速优化:在buildRevChoice中,从choice创建一个set以加快查找速度。
  • 如果您需要性能,请不要对大数组使用 python 循环。使用python/numpy的函数式编程和numpy的向量化。
  • 是的,我知道,但我没有为每个谷歌找到另一个解决方案。想不出一个合理的搜索词组。

标签: python arrays numpy


【解决方案1】:

如果您对掩码数组的内存开销感到满意,这似乎比按索引选择其他值更快,并保留are 中元素的顺序。这是我从 IPython 笔记本中得到的计时结果:

N = 2000000
arr = random.random(N)
percent = 0.10

我的解决方案:

%% timeit
choice = random.choice(N, N*percent)
mask = zeros_like(arr, bool)   
mask[choice] = True
newarr = arr[mask]
revchoice = arr[~mask]

10 个循环,3 个循环中的最佳值:每个循环 18.1 毫秒

0605002的解决方案:

tmp = range(N)
random.shuffle(tmp)
cut = int(N * percent)
newarr, revchoice = tmp[:cut], tmp[cut:]

1 次循环,3 次取胜:每个循环 603 毫秒

【讨论】:

  • 非常感谢,这是两个非常好的解决方案,我会检查哪个更快。我不习惯记忆问题。在什么情况下我不应该使用口罩?
  • 此解决方案(以及 0605002 的另一个解决方案)使用与 arr 大小相同的数组。因此,如果您的数组是可用内存的一半,您将没有足够的空间来创建掩码。如果您避免构建掩码,则只需为索引数组增加 10% 的内存即可。不过,200 万点并不算多。
  • 我已经用时间更新了我的答案。我的解决方案要快一个数量级。
  • 与我的第一个解决方案相比,这确实很快。非常感谢,这很有帮助。我喜欢保留数组的顺序。此外:我必须多次执行该代码(
  • 在堆栈溢出时说“谢谢你,这很有帮助”的最佳方式是接受答案:-)
【解决方案2】:

您可以只random.shuffle 列表,然后随意拆分。

def choice(N, percent):
    tmp = range(N)
    random.shuffle(tmp)
    cut = int(N * percent)
    return tmp[:cut], tmp[cut:]

您将获得两个列表,第一个包含选定的列表,第二个包含其余列表。

【讨论】:

  • 不错的解决方案;虽然我对 random.shuffle 的表现有些警惕。潜在地, random.permutation 具有更好的性能。根据实现方式的不同,np.argsort(random.randint()) 可能仍然是生成排列索引的更快方法。
  • @EelcoHoogendoorn 我没用过numpy,所以我只知道基本的python :) O(n) Fisher Yates Shuffle 算法是改组的好选择吗?
  • 任何你自己实现的算法都是一个糟糕的选择,除非你打算写一个 C 扩展。请注意,我没有对随机播放进行基准测试;我只是想最随机的就地洗牌算法不一定是最有效的。
猜你喜欢
  • 2017-09-16
  • 2014-06-20
  • 2014-04-21
  • 2014-05-15
  • 2017-09-16
  • 2021-12-14
  • 2018-12-14
  • 2017-04-28
  • 2021-12-03
相关资源
最近更新 更多