【问题标题】:Handling corner case of one Numpy array to iterate over处理一个 Numpy 数组的极端情况以进行迭代
【发布时间】:2019-08-22 08:06:58
【问题描述】:

我有一个形状相同的 Numpy 数组列表(但不一定相同 dtype),我想同时迭代所有数组的元素。例如,如果数组是:

>>> a = np.array([[1,2,3], [4,5,6]])
>>> b = np.array([['one','two','three'],['four','five','six']])

我希望对 [a, b] 的迭代产生

[(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four'), (5, 'five'), (6, 'six')]

我发现numpy.nditer几乎能满足我的需要。这有效:

>>> for x, y in np.nditer([a, b]):
...     print('{} {}'.format(x, y))
1 one
2 two
3 three
4 four
5 five
6 six

请注意,迭代器会产生标量元组:

>>> next(np.nditer([a, b]))
(array(1), array('one', dtype='<U5'))

但是,在包含一个数组的列表的极端情况下,np.nditer 直接产生数组元素:

>>> next(np.nditer([a]))
array(1)

我需要它来生成一个包含一个元素的元组,因为我在循环中解压缩函数参数中的迭代值。

我如何说服np.nditer 在遍历一个数组的列表时产生一个单元素元组?

【问题讨论】:

    标签: python arrays numpy iteration


    【解决方案1】:

    一种解决方法是np.atleast_1D:

    a = sum(np.ogrid[2:4, 3:5])
    b = 2*a
    for z in map(np.atleast_1d, np.nditer([a, b])):
        print(np.arange(*z))
    
    #[5 6 7 8 9]
    #[ 6  7  8  9 10 11]
    #[ 6  7  8  9 10 11]
    #[ 7  8  9 10 11 12 13]
    
    for z in map(np.atleast_1d, np.nditer([a])):
        print(np.arange(*z))
    
    #[0 1 2 3 4]
    #[0 1 2 3 4 5]
    #[0 1 2 3 4 5]
    #[0 1 2 3 4 5 6]
    

    请注意,这会将 0D 数组 nditer 返回到正确的标量中。此外,它会生成数组,而不是元组,但因为您只是想将它们放到一个函数中,这并不重要。

    【讨论】:

      【解决方案2】:

      这与nditer 的行为背道而驰。

      也许你总是可以提供一个 None 数组,这样你总是得到一个元组?不过,您必须处理函数中的 None 。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-25
        • 2019-04-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多