【问题标题】:Best way to remove rows that have more of a certain value than a given amount (numpy)删除具有比给定数量更多特定值的行的最佳方法(numpy)
【发布时间】:2018-06-20 19:33:17
【问题描述】:

我创建了一个列大小为d 的数字数组,其中的数字是set(p) 的不同组合。接下来,我想删除比p 中的数字实例更多的行。我可以用for 循环来做到这一点,这是我的代码:

import numpy as np
import itertools as it

from collections import Counter

p = [0,0,0,1,1,1,1,2,2,2,2,2,3,3,3,4,4,4,4,4,5,5,5]
assert (len(set(p)) != 1)
cnt = Counter(p)
pos = np.array(list(it.product(set(p), repeat=d)))
ds = []
for i in range(len(pos)):
    for j, k in cnt.items():
        if len(np.where(pos[i] == j)[0]) > k:
            ds.append(i)
pos = np.delete(pos, ds, axis=0)

我正在寻找一种更快的方法来做到这一点。谢谢!

【问题讨论】:

    标签: python arrays list numpy


    【解决方案1】:

    对于正整数,我们可以使用bincount。因此,我们将使用2D bincount solution 获取pos 中每行的分箱计数,并与p 的分箱计数进行比较,并使用该掩码从pos 中选择有效行,就像这样 -

    # https://stackoverflow.com/a/46256361/ @Divakar
    def bincount2D_vectorized(a):    
        N = a.max()+1
        a_offs = a + np.arange(a.shape[0])[:,None]*N
        return np.bincount(a_offs.ravel(), minlength=a.shape[0]*N).reshape(-1,N)
    
    pos_out = pos[(bincount2D_vectorized(pos)>np.bincount(p)).any(1)]
    

    【讨论】:

    • 感谢您的解决方案!我仍在努力理解它。唯一的问题是,您的输出与我预期的相反。在您的代码中, pos_out 是我希望删除的 pos 行。您建议编辑什么来实现这一点?
    • @JamesCarter 反转掩码:pos[~(bincount2D_vectorized(pos)>np.bincount(p)).any(1)].
    猜你喜欢
    • 2021-03-18
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    相关资源
    最近更新 更多