2D或3D中的Numpy trim_zeros

时间:2019-04-30 08:57:43

标签: python arrays numpy multidimensional-array trim

如何从NumPy数组中删除前导/尾随零? Trim_zeros仅适用于一维。

2 个答案:

答案 0 :(得分:3)

这是一些处理二维数组的代码。

import numpy as np

# Arbitrary array
arr = np.array([
    [0, 0, 0, 0, 0],
    [0, 0, 0, 1, 0],
    [0, 1, 1, 1, 0],
    [0, 1, 0, 1, 0],
    [1, 1, 0, 1, 0],
    [1, 0, 0, 1, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0]
])

nz = np.nonzero(arr)  # Indices of all nonzero elements
arr_trimmed = arr[nz[0].min():nz[0].max()+1,
                  nz[1].min():nz[1].max()+1]

assert np.array_equal(arr_trimmed, [
         [0, 0, 0, 1],
         [0, 1, 1, 1],
         [0, 1, 0, 1],
         [1, 1, 0, 1],
         [1, 0, 0, 1],
    ])

这可以推广到 N 维,如下所示:

def trim_zeros(arr):
    """Returns a trimmed view of an n-D array excluding any outer
    regions which contain only zeros.
    """
    slices = tuple(slice(idx.min(), idx.max() + 1) for idx in np.nonzero(arr))
    return arr[slices]

test = np.zeros((5,5,5,5))
test[1:3,1:3,1:3,1:3] = 1
trimmed_array = trim_zeros(test)
assert trimmed_array.shape == (2, 2, 2, 2)
assert trimmed_array.sum() == 2**4

答案 1 :(得分:0)

以下功能适用于任何尺寸:

 Function Set-ContentType {

    Param (
        [string]$accountName,
        [string]$accessKey,
        [string]$storageContainer
    )

    # Connect to blob storage and get blobs
    $context = New-AzureStorageContext -StorageAccountName $accountName -StorageAccountKey $accessKey
    $blobs = Get-AzureStorageBlob -Container $storageContainer -Context $context -Blob $fileMask

    foreach ($blob in $blobs) {
        if ($blob.ContentType -eq $genericMIME) {
            $blob.ContentType = $targetMIME
        }
    }
 }

可以通过以下方式进行测试:

def trim_zeros(arr, margin=0):
    '''
    Trim the leading and trailing zeros from a N-D array.

    :param arr: numpy array
    :param margin: how many zeros to leave as a margin
    :returns: trimmed array
    :returns: slice object
    '''
    s = []
    for dim in range(arr.ndim):
        start = 0
        end = -1
        slice_ = [slice(None)]*arr.ndim

        go = True
        while go:
            slice_[dim] = start
            go = not np.any(arr[tuple(slice_)])
            start += 1
        start = max(start-1-margin, 0)

        go = True
        while go:
            slice_[dim] = end
            go = not np.any(arr[tuple(slice_)])
            end -= 1
        end = arr.shape[dim] + min(-1, end+1+margin) + 1

        s.append(slice(start,end))
    return arr[tuple(s)], tuple(s)