我正在使用numpy和astropy用Python编写代码。在代码中,我希望创建与我的数据集大体相似的随机numpy数组。之后,我想把这些球坐标的随机数组转换成笛卡尔坐标。不幸的是,我不断得到一个值错误,我完全困惑于为什么会发生这种情况,我曾试图做一些虚拟测试,如如果他们是相同的形状,所有数组的值是合理的,相同的类型,等等,但我卡住了。这是我的密码:
from astropy.coordinates import SkyCoord
from astropy import units as u
import numpy as np
R = 445 + np.random.randn(262615)
print(np.shape(R))
dec = 2 + np.random.randn(262615)
print(np.shape(dec))
ra = 150 + np.random.randn(262615)
print(np.shape(ra))
c = np.zeros(262615)
print(np.shape(c))
for i in range(262615):
c[i] = SkyCoord(ra=ra[i]*u.degree,dec=dec[i]*u.degree,distance=R[i]*u.mpc)
print(c[i])
这是我的错误信息:
PS C:\Users\sirep\Documents\C++ scripts> cd 'c:\Users\sirep\Documents\C++ scripts'; ${env:PYTHONIOENCODING}='UTF-8'; ${env:PYTHONUNBUFFERED}='1'; & 'C:\Users\sirep\Anaconda3\python.exe' 'c:\Users\sirep\.vscode\extensions\ms-python.python-2018.5.0\pythonFiles\PythonTools\visualstudio_py_launcher.py' 'c:\Users\sirep\Documents\C++ scripts' '57764' '34806ad9-833a-4524-8cd6-18ca4aa74f14' 'RedirectOutput,RedirectOutput' 'c:\Users\sirep\Documents\Python Scripts\sph2cart.py'
(262615,)
(262615,)
(262615,)
(262615,)
Traceback (most recent call last):
File "c:\Users\sirep\Documents\Python Scripts\sph2cart.py", line 16, in <module>
c[i] = SkyCoord(ra=ra[i]*u.degree,dec=dec[i]*u.degree,distance=R[i]*u.mpc)
ValueError: setting an array element with a sequence.
谢谢大家抽出时间!你知道吗
我发现了我的错误。SkyCoord返回3个值:x坐标、y坐标和z坐标。我试着给数组的一个元素赋三个值。为了解决这个问题,我必须首先为每个坐标创建3个独立的数组,然后确保每个值在输入到各自的数组时是无量纲的:
我想我应该把我的comment扩展成一个较长的答案,因为这里有一些事情值得解释和澄清,以供将来的读者阅读。你知道吗
你在your answer中写道:
这当然是正确的,但并不完全正确。在原始代码中,您有如下内容:
这已经有点麻烦了,因为您没有指定数据类型,但是默认情况下,数据类型是
float64
,这可能是许多应用程序所需要的(对于这个应用程序来说确实如此)。在任何情况下,Numpy数组类型化意味着,如果您像在原始代码中那样为数组的单个元素赋值:指定的值最好是一个浮点数,或者至少是其他一些可以明确转换为float的数值类型(比如
int
)。对SkyCoord
来说不是这样的,因为正如你所说的,它是一个三维的多重集。我的观点是,一般来说,如果您使用Numpy数组,您需要注意它的dtype
是什么,以及您试图分配给它的元素什么。对于更随意的对象,您可能会得到更清晰的错误,如:仍然不是很好,但至少它证明了它正试图调用
float()
将参数转换为float。但是SkyCoord
会得到不同的结果,因为SkyCoord
可以是一个包含许多坐标的数组的容器,Numpy会看到这一点,并尝试将其视为将一系列值赋给一个标量,这就是所得到的错误。你知道吗顺便说一句,在Numpy中也可以使用structured arrays创建更复杂的数组类型。这允许您创建一个
(x, y, z)
坐标数组,例如:尽管您不能将
SkyCoord
直接赋给这些值中的一个(我认为从技术上讲SkyCoord
被视为无坐标,不管您使用什么坐标系来实例化它,但我可能错了),但是您可以指定例如:但是,这仍然是没有必要的,因为正如我在评论中提到并进一步解释的in the docsa
SkyCoord
可以表示一个坐标数组,如:你可以一次把这些转换成笛卡尔坐标,然后检索x,y,z坐标的独立数组,比如:
这还有一个额外的优点,即使用最合适的长度维度将坐标返回为
Quantity
(在本例中是Mpc,因为这是您给出的距离)。然而,coords.cartesian
本身实际上已经是一个(x, y, z)
坐标的数组,非常像我上面的结构化数组示例(从技术上讲,它不是Numpy数组,但它有许多相同的方法,可以转换为类似的方法):但是这是一个不应该使用的未记录的内部属性(尽管我不知道为什么这个接口没有公开,因为它可能有用…)
最后,我要补充一点,使用这个接口要快得多,因为所有的循环都是向量化的数组操作,大部分都是用C语言编写的。任何时候在Python级别执行诸如分配给数组(
c[i] = ...
)或属性访问(c.cartesian.x.value
)之类的操作时,都会导致严重的性能损失,因为需要将值从C转换为Python,然后再转换回C。使用矢量化操作可以避免所有这些。所以当我制作一个SkyCoord
数组时,我得到:或111ms表示
262615
坐标,如原始示例中所示。然而,用“天真”的方式去做会让我:相关问题 更多 >
编程相关推荐