如何将整齐的1个大小的numpy数组转换为标量?当输入不是1大小的数组时,Numpy“asscalar”会出错。

时间:2016-01-16 01:10:50

标签: python arrays numpy

我对如何以聪明的方式避免以下错误(可能使用正确的numpy函数)抱有这种愚蠢的兴趣。

在许多场合,我需要使用numpy where函数来查找单个项目。但是,有时这个项目不止一次出现,我想使用where函数中的indeces,其中输出将是一个简单的变量(如果它出现一次,字符串或浮点数)或数组(如果多个实例)。

当然,我可以在布尔检查中使用len()并执行转换。但是,我想知道是否有一步到位的方法。我曾经尝试使用asscalar但是,如果输入不是1值数组,则此函数返回并返回错误(我希望它将返回输入值不变:/)。这是代码第二部分的错误再现

import numpy as np

Inventory   = np.array(['Eggs', 'Milk', 'Ham', 'Eggs'])
Drinks      = 'Milk'
Food        = 'Eggs'

index_item_searched = np.where(Inventory == Drinks)
items_instore = np.asscalar(Inventory[index_item_searched])
print 'The shop has', items_instore

index_item_store = np.where(Inventory == Food)
items_instore = np.asscalar(Inventory[index_item_store])
print 'The shop has', items_instore
#I want an output like ['Eggs', 'Eggs']

感谢您的耐心:)

2 个答案:

答案 0 :(得分:1)

如果我正确理解你想要在Inventory中找到一个标记的情况下打印标量,而你想在多个查找的情况下打印一个数组,那么答案是" { {3}}",通常被认为是糟糕的设计。换句话说,有一个原因可以解决为什么在没有一点工作的情况下完成这项工作:如果你的代码根据语义产生不同的结果,那就太危险了。

无论如何,this is not a nice thing to do one of the answers对已经链接的问题提出了一个函数

def scalify(l):
    return l if len(l) > 1 else l[0]

将返回给定的列表,除非列表具有单个元素,在这种情况下它返回元素。正是你需要想要的东西。

示例:

import numpy as np

def scalify(l):
    return l if len(l) > 1 else l[0]

def getitems(inventory,itemtype):
    return inventory[inventory==itemtype]

Inventory   = np.array(['Eggs', 'Milk', 'Ham', 'Eggs'])
Drinks      = 'Milk'
Food        = 'Eggs'

print 'The shop has %s' % scalify(getitems(Inventory,Drinks))

print 'The shop has %s' % scalify(getitems(Inventory,Food))

输出:

The shop has Milk
The shop has ['Eggs' 'Eggs']

答案 1 :(得分:1)

供以后参考:

从numpy v1.16开始,不推荐使用asscalar。请改用np.ndarray.item。就像另一个答案所说的那样,通常只返回一个类型的函数会更好,但是有一些不是这种情况的API(例如__getitem__用于numpy数组甚至是列表!)。所以我建议

from typing import Union, Any

import numpy as np


def maybe_single_item(array: np.ndarray) -> Union[np.ndarray, Any]:
    try:
        return array.item()
    except TypeError:
        return array

(python 3.5 +)