简体   繁体   English

如何在不实际索引数组的情况下获得已知形状数组的索引元素数?

[英]How can I get the number of indexed elements of array of known shape without actually indexing the array?

I have an index IDX (which may be either list of indices, boolean mask, tuple of slices etc.) indexing some abstract numpy array of known shape shape (possibly big).我有一个索引IDX (可能是索引列表、boolean 掩码、切片元组等)索引一些已知shape的抽象 numpy 数组(可能很大)。

I know I can create a dummy array, index it and count the elements:我知道我可以创建一个虚拟数组,对其进行索引并计算元素:

A = np.zeros(shape)
print(A[IDX].size)

Is there any sensible way I can get the number of indexed elements without creating any (potentially big) array?有没有什么明智的方法可以在不创建任何(可能很大)数组的情况下获得索引元素的数量?

I need to tabularize a list of functions at certain points in 3D space.我需要将 3D 空间中某些点的函数列表制成表格。 The points are subset of a rectangular grid given as X , Y , Z lists and IDX is indexing their Cartesian product:这些点是作为XYZ列表给出的矩形网格的子集,并且IDX正在索引它们的笛卡尔积:

XX, YY, ZZ = [A[IDX] for A in np.meshgrid(X, Y, Z)]

The functions accept either X , Y , Z arguments (and return values for their Cartesian product which needs to be indexed) or XX , YY , ZZ .这些函数接受XYZ arguments (并返回需要索引的笛卡尔积的值)或XXYYZZ At the moment I create XX , YY and ZZ arrays whether they are used or not, then I allocate an array for function values:目前我创建XXYYZZ arrays 是否使用它们,然后我为 function 值分配一个数组:

self.TAB = np.full((len(functions), XX.size),
                   np.nan)

but I want to create XX , YY and ZZ only if they are necessary.但我只想在必要时创建XXYYZZ I also want to separate TAB allocation from filling its rows, thus I need to know the number of columns in advance.我还想将TAB分配与填充其行分开,因此我需要提前知道列数。

Just for fun, let's see if we can make a passable approximation here.只是为了好玩,让我们看看我们是否可以在这里做出一个可以通过的近似值。 Your input can be any of the following:您的输入可以是以下任何一种:

  • slice
  • array-like (including scalars)类数组(包括标量)
    • integer arrays do fancy indexing integer arrays 做花式索引
    • boolean arrays do masking boolean arrays 做屏蔽
  • tuple元组

If the input isn't explicitly a tuple to begin with, make it one.如果输入一开始不是明确的元组,则将其设为一个。 Now you can iterate along the tuple and match it to the shape.现在您可以沿着元组进行迭代并将其与形状相匹配。 You can't quite zip them together because boolean arrays eat up multiple element of the shape, and trailing axes are included wholesale.你不能把 zip 放在一起,因为 boolean arrays 会吃掉形状的多个元素,并且尾轴是批发的。

Something like this should do it:这样的事情应该这样做:

def pint(x):
    """ Mimic numpy errors """
    if isinstance(x, bool):
        raise TypeError('an integer is required')
    try:
        y = int(x)
    except TypeError:
        raise TypeError('an integer is required')
    else:
        if y < 0:
            raise ValueError('negative dimensions are not allowed')
    return y


def estimate_size(shape, index):
    # Ensure input is a tuple
    if not isinstance(index, tuple):
        index = (index,)

    # Clean out Nones: they don't change size
    index = tuple(i for i in index if i is not None)

    # Check shape shape and type
    try:
        shape = tuple(shape)
    except TypeError:
        shape = (shape,)
    shape = tuple(pint(s) for s in shape)

    size = 1

    # Check for scalars
    if not shape:
        if index:
            raise IndexError('too many indices for array')
        return size

    # Process index dimensions
    # you could probably use iter(shape) instead of shape[s]
    s = 0

    # fancy indices need to be gathered together and processed as one
    fancy = []

    def get(n):
        nonlocal s
        s += n
        if s > len(shape):
            raise IndexError('too many indices for array')
        return shape[s - n:s]

    for ind in index:
        if isinstance(ind, slice):
            ax, = get(1)
            size *= len(range(*ind.indices(ax)))
        else:
            ind = np.array(ind, ndmin=1, subok=True, copy=False)
            if ind.dtype == np.bool_:
                # Boolean masking
                ax = get(ind.ndim)
                if ind.shape != ax:
                    k = np.not_equal(ind.shape, ax).argmax()
                    IndexError(f'IndexError: boolean index did not match indexed array along dimension {s - n.ndim + k}; dimension is {shape[s - n.ndim + k]} but corresponding boolean dimension is {ind.shape[k]}')
                size *= np.count_nonzero(ind)
            elif np.issubdtype(ind.dtype, np.integer):
                # Fancy indexing
                ax, = get(1)
                if ind.min() < -ax or ind.max() >= ax:
                    k = ind.min() if ind.min() < -ax else ind.max()
                    raise IndexError(f'index {k} is out of bounds for axis {s} with size {ax}')
                fancy.append(ind)
            else:
                raise IndexError('arrays used as indices must be of integer (or boolean) type')

    # Add in trailing dimensions
    size *= np.prod(shape[s:])

    # Add fancy indices
    if fancy:
        size *= np.broadcast(*fancy).size

    return size

This is only an approximation.这只是一个近似值。 You will need to change it any time the API changes, and it already has some incomplete features.您需要随时更改 API 更改,并且它已经具有一些不完整的功能。 Testing, fixing and, expanding is left as an exercise for the reader.测试、修复和扩展留给读者作为练习。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在没有循环的numpy数组中为所有奇数或偶数索引元素添加一个数字 - add a number to all odd or even indexed elements in numpy array without loops 如何创建形状为(0,2)的numpy数组? - How can I create a numpy array with shape (0, 2)? 用Python中相同形状的逻辑数组索引数组 - Indexing an array with a logical array of the same shape in Python 如何找到 numpy 数组的第一个最小数量,然后在不对数组进行排序的情况下找到第二个最小数量? - How can I find the first minimum number of numpy array, then the second minimum number without sorting the array? 如何修复索引数组中最大值的错误? - How can I fix the error indexing the maximum in an array? 如何获得此 pandas 阵列形状以匹配此 numpy 阵列形状? - How do I get this pandas array shape to match this numpy array shape? 如何在np.array中获取每个数字的指数? - How can I get the exponent of each number in a np.array? 形状不匹配:形状(2,)的值数组无法广播到形状(1,)的索引结果 - shape mismatch: value array of shape (2,) could not be broadcast to indexing result of shape (1,) 如何在 python arrays 中添加由另一个数组的元素索引的行? - How do I add rows within python arrays that are indexed by elements of another array? 如何在没有指定元素数量的情况下创建一个 numpy 数组? - How to create a numpy array without having a specified number of elements?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM