当前位置: 首页 > 知识库问答 >
问题:

在每行的特定值内计算numpy数组中的实例数

司空俊雅
2023-03-14

我有一个像这样的数字数组

[[ 0, 57],
 [ 7, 72],
 [ 2, 51],
 [ 8, 67],
 [ 4, 42]]

我想找出每一行,第二列中有多少元素在该行第二列值的一定距离内(比如10)。所以在这个例子中,这里的解决方案是

[[ 0, 57, 3],
 [ 7, 72, 2],
 [ 2, 51, 3],
 [ 8, 67, 3],
 [ 4, 42, 2]]

所以[first row,third column]是3,因为第二列(57,51,67)中有3个元素在距离57的10范围内。每行的情况类似

任何帮助都将不胜感激!

共有2个答案

左丘元徽
2023-03-14

这是一种非广播方法,它利用了一个事实,即要知道有多少数字在10的3以内,可以减去数字的数量

import numpy as np

def broadcast(x, width):
    # for comparison
    return (np.abs(x[:,None] - x) <= width).sum(1)


def largest_leq(arr, x, allow_equal=True):
    maybe = np.searchsorted(arr, x)
    maybe = maybe.clip(0, len(arr) - 1)
    above = arr[maybe] > x if allow_equal else arr[maybe] >= x
    maybe[above] -= 1
    return maybe

def faster(x, width):
    uniq, inv, counts = np.unique(x, return_counts=True, return_inverse=True)
    counts = counts.cumsum()

    low_bounds = uniq - width
    low_ix = largest_leq(uniq, low_bounds, allow_equal=False)
    low_counts = counts[low_ix]
    low_counts[low_ix < 0] = 0

    high_bounds = uniq + width
    high_counts = counts[largest_leq(uniq, high_bounds)]

    delta = high_counts - low_counts
    out = delta[inv]
    return out

这通过了我的测试:

for width in range(1, 10):
    for window in range(5):
        for trial in range(10):
            x = np.random.randint(0, 10, width)
            b = broadcast(x, window).tolist()
            f = faster(x, window).tolist()
            assert b == f

即使在较大的尺寸下也表现良好:

In [171]: x = np.random.random(10**6)

In [172]: %time faster(x, 0)
Wall time: 386 ms
Out[172]: array([1, 1, 1, ..., 1, 1, 1], dtype=int64)

In [173]: %time faster(x, 1)
Wall time: 372 ms
Out[173]: array([1000000, 1000000, 1000000, ..., 1000000, 1000000, 1000000], dtype=int64)

In [174]: x = np.random.randint(0, 10, 10**6)

In [175]: %timeit faster(x, 3)
10 loops, best of 3: 83 ms per loop
韩梓
2023-03-14

这里有一种方法利用广播外部减法-

(np.abs(a[:,1,None] - a[:,1]) <= 10).sum(1)

外减法内置count_nonzero计数-

np.count_nonzero(np.abs(np.subtract.outer(a[:,1],a[:,1]))<=10,axis=1)

样本运行-

# Input array
In [23]: a
Out[23]: 
array([[ 0, 57],
       [ 7, 72],
       [ 2, 51],
       [ 8, 67],
       [ 4, 42]])

# Get count
In [24]: count = (np.abs(a[:,1,None] - a[:,1]) <= 10).sum(1)

In [25]: count
Out[25]: array([3, 2, 3, 3, 2])

# Stack with input
In [26]: np.c_[a,count]
Out[26]: 
array([[ 0, 57,  3],
       [ 7, 72,  2],
       [ 2, 51,  3],
       [ 8, 67,  3],
       [ 4, 42,  2]])

或者使用SciPy的cdist-

In [53]: from scipy.spatial.distance import cdist

In [54]: (cdist(a[:,None,1],a[:,1,None], 'minkowski', p=2)<=10).sum(1)
Out[54]: array([3, 2, 3, 3, 2])

对于输入中的百万行,我们可能需要求助于循环行-

n = len(a)
count = np.empty(n, dtype=int)
for i in range(n):
    count[i] = np.count_nonzero(np.abs(a[:,1]-a[i,1])<=10)
 类似资料:
  • 问题内容: 如何计算值等于常数的数组中元素的数量?例, 我怎么才能直接知道里面有多少“本”? 问题答案:

  • 问题内容: 我试图根据条件计算某个值在多维数组中出现的次数。这是一个示例数组; 如果要显示所有绿色水果,可以执行以下操作(让我知道这是否是最佳方法); 这将输出; 太好了,我可以在那里看到它们是2个值,但是实际上我如何才能让PHP计算绿色的水果数量并将其放在变量中,以便我在脚本中进一步使用以解决问题?例如,我想做类似的事情; 我看过count(); 但是我看不到任何添加“ WHERE / cond

  • 问题内容: 我有以下JSON数组,我想创建对象表单状态键计数 要计算状态键值并创建以下对象 问题答案: 使用 方法 虽然可以使用 具有相同代码的方法。

  • 问题内容: 我有一个NumPy值数组。我想计算在特定范围内有多少这些值,例如x <100和x> 25。我已经读过有关计数器的信息,但它似乎仅对指定值有效,对值范围无效。我已经搜索过,但是没有发现有关我的特定问题的任何信息。如果有人可以指出适当的文档,我将不胜感激。谢谢 我已经试过了 但这只是给我25到99之间的数字。 编辑 我正在使用的数据是由另一个程序创建的。然后,我使用脚本读取数据并将其存储为

  • 问题内容: 说我有一个像这样的数组: 如何计算具有给定值的数字(在示例中为空白)? 而且有效吗?(大约十二个数组,每个数组包含数百个元素)此示例超时(超过30秒): 在这种情况下,空白元素的数量为3。 问题答案: 如何使用array_count _values来获得一个为您计算一切的数组?

  • 问题内容: 有没有一种快速的方法用(例如)线性插值替换numpy数组中的所有NaN值? 例如, 将被转换成 问题答案: 让我们首先定义一个简单的辅助函数,以使其更直接地处理NaN的索引和逻辑索引: 现在可以像这样使用: -– 尽管指定一个单独的函数来执行以下操作似乎有点过头了: 它最终将支付股息。 因此,每当您处理与NaNs相关的数据时,只需将其所需的所有(新的与NaN相关的新功能)封装在某些特定