用对象实例填充 NumPy 数组?
Filling NumPy array with object instances?
我正在尝试将 astropy
Angles
的对象实例添加到 NumPy
数组,但出现错误:
ValueError: setting an array element with a sequence.
Angle
对象看起来像这样:
<Angle 1.2557346257567 deg>
如果我将它们放在一个正常的 Python 列表中,那么我会得到:
s = [<Angle 1.2562500714928306 deg>,
<Angle 1.2562500714928306 deg>,
<Angle 1.2562500714928306 deg>]
len(s)
>>> 3
len(s[0])
>>> TypeError: 'Angle' object with a scalar value has no len()
所以,我的第一个问题是,Python 对象在什么方面是一个序列?而且,由于需要将 numpy 数组初始化为特定维度,我如何找到此对象的 "length" 以便我可以将它们加载到 numpy 数组中?
我没有 astrop
包,也不知道 Angle
对象的详细信息。但我可以做一些 Python 和 numpy 观察。
<Angle 1.2557346257567 deg>
是此对象的字符串表示形式,由其 __repr__
方法生成。
len(s[0])
的 TypeError 意味着该对象没有 __len__
方法。它不是列表的子类,也不是专门的 numpy
数组。检查它的文档。它可能有产生一个或多个数值的方法。
你没有说你是如何尝试 'add' 一个数组的角度,或者什么样的数组。如果数组是数字,例如dtype=float
,然后做
A[0]= <Angle...>
是行不通的,因为 Angle
不是数字,也不会产生数字——至少在没有某种方法的情况下不会。您需要告诉我们这个目标数组应该包含什么。数字、角度物体?
您可以构建一个包含对象的数组。 np.array(s)
可能有效。它在列表包含字典对象时执行。
In [67]: ll
Out[67]: [{1: 2}, {}, {'a': 1, 'b': 2}]
In [68]: np.array(ll)
Out[68]: array([{1: 2}, {}, {'b': 2, 'a': 1}], dtype=object)
但是 np.array([...])
使用起来可能很棘手,因为它旨在生成多维数字数组 - 如果可能的话。
或者您可能需要创建 A = np.zeros((3,),dtype=object)
数组,并单独赋值,A[0]=s[0]
。但是这样的对象数组只是列表的一个变体。它不是二维数组。
来自之前的 astropy
个问题:
Angle(angles_quantity).wrap_at('360d').value # This returns a simple ndarray again.
=================
深入研究文档和 astropy github 代码,我看到 Angle
是 Quantity
的子类,Quantity
是 ndarray
的子类。它实际上是一个具有适当 unit
定义的数组(或标量)。
.value
方法returnsself.view(np.ndarray)
,除非它的形状是0d,在这种情况下它returnsself.item()
,标量值。
因此您应该能够定义具有多个值的 Angle
,例如
Angle([1.23, 1.24, 1.25])
不知道能不能把多个Angles
拼成一个
Angle(s)
其中 s
是您的 Angle 对象列表,可能会起作用。我没有看到 concatenate
或 stack
.
的 Angle
版本
您可以将数组的 dtype
设置为 object
,一个简单的例子是
import numpy as np
from astropy.coordinates import Angle
a, b, c = Angle('1.2562500714928306d'), Angle('1.2562500714928306d'), Angle('1.2562500714928306d')
s = np.array([a, b, c], dtype=object)
不要创建 Angle
个对象的列表或数组。
相反,将 Angle
(和类似的 astropy 类)视为添加单元的容器对象,并使用列表或数组对其进行初始化。
例如:
>>> from astropy.coordinates import Angle
>>> from astropy import units
>>> angles = Angle([0, 30, 60, 90], unit=units.degree)
>>> angles
<Angle [ 0., 30., 60., 90.] deg>
或
>>> angles = Angle(np.linspace(0, 90, 15, endpoint=True), unit=units.degree)
>>> angles
<Angle [ 0. , 6.42857143, 12.85714286, 19.28571429, 25.71428571,
32.14285714, 38.57142857, 45. , 51.42857143, 57.85714286,
64.28571429, 70.71428571, 77.14285714, 83.57142857, 90. ] deg>
>>> len(angles)
15
这是一种更有效的使用 astropy 类 的方法:您现在可以简单地将 angles
乘以一个值,或对其执行其他操作,就像对 numpy 数组一样。
我正在尝试将 astropy
Angles
的对象实例添加到 NumPy
数组,但出现错误:
ValueError: setting an array element with a sequence.
Angle
对象看起来像这样:
<Angle 1.2557346257567 deg>
如果我将它们放在一个正常的 Python 列表中,那么我会得到:
s = [<Angle 1.2562500714928306 deg>,
<Angle 1.2562500714928306 deg>,
<Angle 1.2562500714928306 deg>]
len(s)
>>> 3
len(s[0])
>>> TypeError: 'Angle' object with a scalar value has no len()
所以,我的第一个问题是,Python 对象在什么方面是一个序列?而且,由于需要将 numpy 数组初始化为特定维度,我如何找到此对象的 "length" 以便我可以将它们加载到 numpy 数组中?
我没有 astrop
包,也不知道 Angle
对象的详细信息。但我可以做一些 Python 和 numpy 观察。
<Angle 1.2557346257567 deg>
是此对象的字符串表示形式,由其 __repr__
方法生成。
len(s[0])
的 TypeError 意味着该对象没有 __len__
方法。它不是列表的子类,也不是专门的 numpy
数组。检查它的文档。它可能有产生一个或多个数值的方法。
你没有说你是如何尝试 'add' 一个数组的角度,或者什么样的数组。如果数组是数字,例如dtype=float
,然后做
A[0]= <Angle...>
是行不通的,因为 Angle
不是数字,也不会产生数字——至少在没有某种方法的情况下不会。您需要告诉我们这个目标数组应该包含什么。数字、角度物体?
您可以构建一个包含对象的数组。 np.array(s)
可能有效。它在列表包含字典对象时执行。
In [67]: ll
Out[67]: [{1: 2}, {}, {'a': 1, 'b': 2}]
In [68]: np.array(ll)
Out[68]: array([{1: 2}, {}, {'b': 2, 'a': 1}], dtype=object)
但是 np.array([...])
使用起来可能很棘手,因为它旨在生成多维数字数组 - 如果可能的话。
或者您可能需要创建 A = np.zeros((3,),dtype=object)
数组,并单独赋值,A[0]=s[0]
。但是这样的对象数组只是列表的一个变体。它不是二维数组。
来自之前的 astropy
个问题:
Angle(angles_quantity).wrap_at('360d').value # This returns a simple ndarray again.
=================
深入研究文档和 astropy github 代码,我看到 Angle
是 Quantity
的子类,Quantity
是 ndarray
的子类。它实际上是一个具有适当 unit
定义的数组(或标量)。
.value
方法returnsself.view(np.ndarray)
,除非它的形状是0d,在这种情况下它returnsself.item()
,标量值。
因此您应该能够定义具有多个值的 Angle
,例如
Angle([1.23, 1.24, 1.25])
不知道能不能把多个Angles
拼成一个
Angle(s)
其中 s
是您的 Angle 对象列表,可能会起作用。我没有看到 concatenate
或 stack
.
Angle
版本
您可以将数组的 dtype
设置为 object
,一个简单的例子是
import numpy as np
from astropy.coordinates import Angle
a, b, c = Angle('1.2562500714928306d'), Angle('1.2562500714928306d'), Angle('1.2562500714928306d')
s = np.array([a, b, c], dtype=object)
不要创建 Angle
个对象的列表或数组。
相反,将 Angle
(和类似的 astropy 类)视为添加单元的容器对象,并使用列表或数组对其进行初始化。
例如:
>>> from astropy.coordinates import Angle
>>> from astropy import units
>>> angles = Angle([0, 30, 60, 90], unit=units.degree)
>>> angles
<Angle [ 0., 30., 60., 90.] deg>
或
>>> angles = Angle(np.linspace(0, 90, 15, endpoint=True), unit=units.degree)
>>> angles
<Angle [ 0. , 6.42857143, 12.85714286, 19.28571429, 25.71428571,
32.14285714, 38.57142857, 45. , 51.42857143, 57.85714286,
64.28571429, 70.71428571, 77.14285714, 83.57142857, 90. ] deg>
>>> len(angles)
15
这是一种更有效的使用 astropy 类 的方法:您现在可以简单地将 angles
乘以一个值,或对其执行其他操作,就像对 numpy 数组一样。