Python 反转numpy数组中随机选择的关键点

Python 反转numpy数组中随机选择的关键点,python,arrays,numpy,Python,Arrays,Numpy,我有一个巨大的np.array,名为arr,有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=[]

我有一个巨大的np.array,名为arr,有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
你能想出一个方法来加快进度吗?

你可以只列出列表,然后根据自己的喜好将其拆分

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

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

如果您对掩码数组的内存开销感到满意,那么这似乎比按索引选择其他值要快,并保留
中元素的顺序。以下是我从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]
tmp = range(N)
random.shuffle(tmp)
cut = int(N * percent)
newarr, revchoice = tmp[:cut], tmp[cut:]
10个环路,最佳3个:每个环路18.1毫秒

0605002的解决方案:

%% timeit
choice = random.choice(N, N*percent)
mask = zeros_like(arr, bool)   
mask[choice] = True
newarr = arr[mask]
revchoice = arr[~mask]
tmp = range(N)
random.shuffle(tmp)
cut = int(N * percent)
newarr, revchoice = tmp[:cut], tmp[cut:]

1个循环,每个循环最好3:603毫秒

快速优化:在
buildRevChoice
中,从
choice
创建一个
集合
,以加快查找速度。如果需要性能,请不要对大数组使用python循环。使用python/numpy的函数式编程和numpy的矢量化。是的,我知道,但我没有在谷歌上找到其他解决方案。想不出一个合理的搜索短语。这是一个不错的解决方案;虽然我对random.shuffle的性能有些担心。随机排列可能具有更好的性能。根据实现方式的不同,np.argsort(random.randint())可能是生成置换索引的更快方法。@eelcoogendoorn我还没有使用
numpy
,所以我只知道基本的python:)O(n)会不会Fisher-Yates Shuffle算法是一个很好的洗牌选择?任何你自己实现的算法都是一个糟糕的选择,除非你打算写一个C扩展。注意,我还没有对shuffle进行基准测试;我只是想,最随机的就地洗牌算法不一定是最有效的。非常感谢,这是两个非常好的解决方案,我将检查哪一个更快。我不习惯记忆问题。在这种情况下,我不应该使用掩码?此解决方案(以及0605002的另一个解决方案)使用与
arr
大小相同的数组。因此,如果您的阵列只有可用内存的一半大,您将没有足够的空间来创建掩码。如果避免构建掩码,索引数组的内存只需增加10%。不过200万分并不是很多。我已经用时间更新了我的答案。我的解快了一个数量级。这比我的第一个解快得多。非常感谢,这很有帮助。我喜欢保持数组的顺序。此外:我必须多次执行该代码(对堆栈溢出说“谢谢你,这很有帮助”的最好方式是接受答案:-)