为什么 NumPy 将对象转换为浮点数?
Why NumPy is casting objects to floats?
我正在尝试在 NumPy 数组中存储间隔(使用其特定的算法)。如果我使用自己的间隔 class,它可以工作,但是我的 class 很差,我的 Python 知识有限。
我知道 pyInterval 并且非常完整。它涵盖了我的问题。唯一不起作用的是将 pyInterval 对象存储在 NumPy 数组中。
class Interval(object):
def __init__(self, lower, upper = None):
if upper is None:
self.upper = self.lower = lower
elif lower <= upper:
self.lower = lower
self.upper = upper
else:
raise ValueError(f"Lower is bigger than upper! {lower},{upper}")
def __repr__(self):
return "Interval " + str((self.lower,self.upper))
def __mul__(self,another):
values = (self.lower * another.lower,
self.upper * another.upper,
self.lower * another.upper,
self.upper * another.lower)
return Interval(min(values), max(values))
import numpy as np
from interval import interval
i = np.array([Interval(2,3), Interval(-3,6)], dtype=object) # My class
ix = np.array([interval([2,3]), interval([-3,6])], dtype=object) # pyInterval
这些是结果
In [30]: i
Out[30]: array([Interval (2, 3), Interval (-3, 6)], dtype=object)
In [31]: ix
Out[31]:
array([[[2.0, 3.0]],
[[-3.0, 6.0]]], dtype=object)
pyInterval 的间隔已转换为浮点列表的列表。如果他们保留区间算术,这不是问题...
In [33]: i[0] * i[1]
Out[33]: Interval (-9, 18)
In [34]: ix[0] * ix[1]
Out[34]: array([[-6.0, 18.0]], dtype=object)
Out[33]
是希望的输出。使用 pyInterval 的输出不正确。显然使用原始 pyInterval 它就像一个魅力
In [35]: interval([2,3]) * interval([-3,6])
Out[35]: interval([-9.0, 18.0])
Here 是 pyInterval 源代码。我不明白为什么使用这个对象 NumPy 不能像我预期的那样工作。
NumPy 将每个间隔视为两个数字的数组,并且它执行您不想要的逐元素乘法。试试这个:
interval.__mul__(ix[0], ix[1])
那就是直接调用你要调用的函数。它应该给你你需要的答案,即使它不是很漂亮。要将它变成适用于整个阵列的东西,您可以这样做:
itvmul = np.vectorize(interval.__mul__)
这将允许您对间隔数组进行元素乘法:https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.vectorize.html
公平地说,numpy.ndarray
构造函数确实很难推断应该将哪种数据放入其中。它接收类似于元组列表的对象并使用它。
但是,您可以通过不让构造函数猜测数据的形状来稍微帮助它:
a = interval([2,3])
b = interval([-3,6])
ll = [a,b]
ix = np.empty((len(ll),), dtype=object)
ix[:] = [*ll]
ix[0]*ix[1] #interval([-9.0, 18.0])
我正在尝试在 NumPy 数组中存储间隔(使用其特定的算法)。如果我使用自己的间隔 class,它可以工作,但是我的 class 很差,我的 Python 知识有限。
我知道 pyInterval 并且非常完整。它涵盖了我的问题。唯一不起作用的是将 pyInterval 对象存储在 NumPy 数组中。
class Interval(object):
def __init__(self, lower, upper = None):
if upper is None:
self.upper = self.lower = lower
elif lower <= upper:
self.lower = lower
self.upper = upper
else:
raise ValueError(f"Lower is bigger than upper! {lower},{upper}")
def __repr__(self):
return "Interval " + str((self.lower,self.upper))
def __mul__(self,another):
values = (self.lower * another.lower,
self.upper * another.upper,
self.lower * another.upper,
self.upper * another.lower)
return Interval(min(values), max(values))
import numpy as np
from interval import interval
i = np.array([Interval(2,3), Interval(-3,6)], dtype=object) # My class
ix = np.array([interval([2,3]), interval([-3,6])], dtype=object) # pyInterval
这些是结果
In [30]: i
Out[30]: array([Interval (2, 3), Interval (-3, 6)], dtype=object)
In [31]: ix
Out[31]:
array([[[2.0, 3.0]],
[[-3.0, 6.0]]], dtype=object)
pyInterval 的间隔已转换为浮点列表的列表。如果他们保留区间算术,这不是问题...
In [33]: i[0] * i[1]
Out[33]: Interval (-9, 18)
In [34]: ix[0] * ix[1]
Out[34]: array([[-6.0, 18.0]], dtype=object)
Out[33]
是希望的输出。使用 pyInterval 的输出不正确。显然使用原始 pyInterval 它就像一个魅力
In [35]: interval([2,3]) * interval([-3,6])
Out[35]: interval([-9.0, 18.0])
Here 是 pyInterval 源代码。我不明白为什么使用这个对象 NumPy 不能像我预期的那样工作。
NumPy 将每个间隔视为两个数字的数组,并且它执行您不想要的逐元素乘法。试试这个:
interval.__mul__(ix[0], ix[1])
那就是直接调用你要调用的函数。它应该给你你需要的答案,即使它不是很漂亮。要将它变成适用于整个阵列的东西,您可以这样做:
itvmul = np.vectorize(interval.__mul__)
这将允许您对间隔数组进行元素乘法:https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.vectorize.html
公平地说,numpy.ndarray
构造函数确实很难推断应该将哪种数据放入其中。它接收类似于元组列表的对象并使用它。
但是,您可以通过不让构造函数猜测数据的形状来稍微帮助它:
a = interval([2,3])
b = interval([-3,6])
ll = [a,b]
ix = np.empty((len(ll),), dtype=object)
ix[:] = [*ll]
ix[0]*ix[1] #interval([-9.0, 18.0])