【问题标题】:How to determine slices that contains "None" and ":" in numpy?如何在numpy中确定包含“None”和“:”的切片?
【发布时间】:2020-12-23 22:06:30
【问题描述】:

我正在做itertools.product 的替代练习,我的方法是使用np.broadcast

import numpy as np
x = np.array([4,3,1])
y = np.array([2,4,0])
z = np.array([0,1,2])
ix = np.broadcast(x[:,None,None], y[None,:,None], z[None, None, :])
print(*ix)

这次它工作正常,但如果我愿意,如何以自动方式创建所有这些“眼睛排列”的新轴,比如像这样的 7 个维度:

[:,None,None,None,None,None,None]
[None,:,None,None,None,None,None]
[None,None,:,None,None,None,None]
[None,None,None,:,None,None,None]
[None,None,None,None,:,None,None]
[None,None,None,None,None,:,None]
[None,None,None,None,None,None,:]

我希望像np.ix_ 这样的东西允许在分配这些切片时使用所有这些Nones 和:s。

【问题讨论】:

    标签: python numpy slice numpy-slicing


    【解决方案1】:

    方法#1

    同样的眼睛排列可以用来重塑所有参与的阵列 -

    A = [x,y,z] # all arrays
    s = 1-2*np.eye(len(A), dtype=int)
    out = [a.reshape(i) for i,a in zip(s,A)]
    

    这是使用s 塑造的技巧部分:

    In [53]: s
    Out[53]: 
    array([[-1,  1,  1], # reshape to keep all axes singleton except first
           [ 1, -1,  1], #                                       .. second 
           [ 1,  1, -1]]) #                                      ... third
    

    因此,考虑到[-1, 1, 1] 是重塑以保持所有轴单例,除了第一个。这与[:,None,None] 等相同。

    方法 #2

    使用相同的eye-arrangement得到一个indexer -

    idx = np.where(np.eye(len(A)), Ellipsis, None)
    out = [a[tuple(i)] for a,i in zip(A,idx)]
    

    索引器是:

    In [77]: idx
    Out[77]: 
    array([[Ellipsis, None, None],
           [None, Ellipsis, None],
           [None, None, Ellipsis]], dtype=object)
    

    【讨论】:

    • 谢谢。这是我之前想不到的非常漂亮的方法
    • 听起来像Ellipsisslice() 的替代品。但是性能呢?我的意思是使用 x.reshape(1,-1,-1)x[Ellipsis, None, None]?
    • @mathfux 两者都在创建视图。所以,不要认为性能应该是一个问题。 Elllipsis is an alias for "..."。在我们的例子中,它等同于您的“:”。
    【解决方案2】:

    每个索引都是一个n-element 元组。每个元组的diagonal元素,即ith元组的ith元素,是一个slice对象。具体来说,:slice(None) 的缩写。 (一般来说,x:y:z 是对象slice(x, y, z),任何缺少的元素都是None,但至少必须提供一个参数)。

    arguments = [(None,)*i + (slice(None),) + (None,)*(6-i) for i in range(7)]
    # E.g., i == 0 -> () + (slice(None),) + (None, None, None, None, None, None)
    #              == (slice(None), None, None, None, None, None, None)
    ix = np.broadcast(*(x[arg] for arg in arguments))
    

    【讨论】:

    • 谢谢。所以: 可以替换为slice(),这正是我一直在寻找的。​​span>
    • 不应该是slice(None)吗?
    • @hpaulj 确实应该。我想我记得slice() 被允许。
    猜你喜欢
    • 2015-05-21
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 2017-07-08
    • 1970-01-01
    • 2020-06-08
    • 1970-01-01
    • 2020-12-17
    相关资源
    最近更新 更多