簡體   English   中英

在不使用for循環的情況下刪除numpy數組的前導零

[英]Removing leading zeros of a numpy array without using a for loop

如何在不使用循環的情況下僅從numpy數組中刪除前導零?

import numpy as np

x = np.array([0,0,1,1,1,1,0,1,0,0])

# Desired output
array([1, 1, 1, 1, 0, 1, 0, 0])

我寫了以下代碼

x[min(min(np.where(x>=1))):] 

我想知道是否有更有效的解決方案。

您可以使用np.trim_zeros(x, 'f')

'f'表示從前面修剪零。 選項'b'將從后面修剪零。 默認選項'fb'從兩側修剪它們。

x = np.array([0,0,1,1,1,1,0,1,0,0])
# [0 0 1 1 1 1 0 1 0 0]
np.trim_zeros(x, 'f')
# [1 1 1 1 0 1 0 0]

由於np.trim_zeros 使用for循環 ,因此這是一個真正的矢量化解決方案:

x = x[np.where(x != 0)[0][0]:]

但是我不確定它在哪一點上比np.trim_zeros更有效率。 在最壞的情況下(即具有大多數前導零的數組),它將更有效。

無論如何,它可以是一個有用的學習示例。

雙面裝飾:

>>> idx = np.where(x != 0)[0]
>>> x = x[idx[0]:1+idx[-1]]

這是一種短路的numpy方法。 它利用了任何(?)dtype的0表示都是零字節的事實。

import numpy as np
import itertools

# check assumption that for example 0.0f is represented as 00 00 00 00
allowed_dtypes = set()
for dt in map(np.dtype, itertools.chain.from_iterable(np.sctypes.values())):
    try:
        if not np.any(np.zeros((1,), dtype=dt).view(bool)):
            allowed_dtypes.add(dt)
    except:
        pass

def trim_fast(a):
    assert a.dtype in allowed_dtypes
    cut = a.view(bool).argmax() // a.dtype.itemsize
    if a[cut] == 0:
        return a[:0]
    else:
        return a[cut:]

與其他方法比較:

在此輸入圖像描述

代碼生成圖:

def np_where(a):
    return a[np.where(a != 0)[0][0]:]

def np_trim_zeros(a):
    return np.trim_zeros(a, 'f')

import perfplot

tf, nt, nw = trim_fast, np_trim_zeros, np_where
def trim_fast(A): return [tf(a) for a in A]
def np_trim_zeros(A): return [nt(a) for a in A]
def np_where(A): return [nw(a) for a in A]

perfplot.save('tz.png',
    setup=lambda n: np.clip(np.random.uniform(-n, 1, (100, 20*n)), 0, None),
    n_range=[2**k for k in range(2, 11)],
    kernels=[
        trim_fast,
        np_where,
        np_trim_zeros
        ],
    logx=True,
    logy=True,
    xlabel='zeros per nonzero',
    equality_check=None
    )

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM