如何在.dat文件中写入数据Python新行多列表卫星轨道
我创建了一个函数来生成和传播卫星轨道。现在,我想将所有数据保存在一个.dat文件中。我不知道我需要多少for循环,也不知道如何做 我希望每个传播步骤的时间、纬度、经度和高度都在一条线上 数据代码: .dat文件中所需的输出: J2000时间,纬度,经度,高度如何在.dat文件中写入数据Python新行多列表卫星轨道,python,data-analysis,astropy,orbital-mechanics,Python,Data Analysis,Astropy,Orbital Mechanics,我创建了一个函数来生成和传播卫星轨道。现在,我想将所有数据保存在一个.dat文件中。我不知道我需要多少for循环,也不知道如何做 我希望每个传播步骤的时间、纬度、经度和高度都在一条线上 数据代码: .dat文件中所需的输出: J2000时间,纬度,经度,高度 1085.0, 48.6, -144.2, 264779.5 2170.0, 26.5, -50.4, 262446.1 3255.0, -28.7, -1.6, 319661.8 4340.1, -48.0, 91.5, 35571
1085.0, 48.6, -144.2, 264779.5
2170.0, 26.5, -50.4, 262446.1
3255.0, -28.7, -1.6, 319661.8
4340.1, -48.0, 91.5, 355717.2
5425.1, 0.1, 152.8, 06129.0
完整代码:
orbitPropandcoordTrans5,-34963095,0.0073662,51.5946,154.8079,103.6176,257.3038,15.92610159可能最简单的方法是使用拉链: 数据=ZIPMYORBITJ2000时间、纬度、经度、高度
因此,数据将具有您希望序列化的格式。不要忘记序列化您想要的标题。为了回答您的一般问题,您可以先创建Numpy数组而不是列表,而不是定义一堆附加和使用起来很慢的Python列表,特别是当您在扩展分辨率时处理大量值时。初始化Numpy数组时,通常需要指定数组的大小,但在这种情况下,这很容易,因为您知道需要多少次传播。例如:
>>> orbitX = np.empty(propNum, dtype=float)
创建一个由propNum浮点值组成的空Numpy数组此处为空表示数组未使用任何值初始化这是创建新数组的最快方法,因为我们稍后将填充其中的所有值
然后在循环中,而不是使用orbitX.appendx,您将分配给数组中与当前记号对应的值:orbitX[i]=x。其他情况也一样
然后有几种方法可以输出数据,但是使用Astropy提供了很大的灵活性。您可以轻松创建包含所需列的表,如:
>>> from astropy.table import Table
>>> table = Table([J2000, lat, lon, alt], names=('J2000', 'lat', 'lon', 'alt'))
拥有Table对象的好处在于,有大量的输出格式选项。例如,在Python提示符下:
>>> table
J2000 lat lon alt
float64 float64 float64 float64
------------- -------------- -------------- -------------
1085.01128806 48.5487129749 -144.175054697 264779.500823
2170.02257613 26.5068122883 -50.3805485685 262446.085716
3255.03386419 -28.7915478311 -1.6090285674 319661.817451
4340.04515225 -48.0536526356 91.5416828221 355717.274021
5425.05644032 0.084422392655 152.811717713 306129.02576
<>要首先输出文件,就必须考虑如何将数据格式化。已经有许多常见的数据格式可以考虑使用,但是它取决于数据是什么,谁将使用它。或者更确切地说,这可能意味着什么。但在您的问题中,您指出您想要的是所谓的逗号分隔值CSV,其中数据的格式为向下的列,行中的每个值用逗号分隔。Table类可以非常轻松地输出CSV和任何变量:
>>> import sys
>>> table.write(sys.stdout, format='ascii.csv') # Note: I'm just using sys.stdout for demonstration purposes; normally you would give a filename
J2000,lat,lon,alt
1085.011288063746,48.54871297493748,-144.17505469691633,264779.5008225624
2170.022576127492,26.506812288280788,-50.38054856853237,262446.0857159357
3255.0338641912376,-28.79154783108773,-1.6090285674024463,319661.81745081506
4340.045152254984,-48.05365263557444,91.54168282208444,355717.2740210131
5425.05644031873,0.08442239265500713,152.81171771323176,306129.0257600865
不过,还有很多其他选择。例如,如果您希望在对齐的列中对数据进行良好的格式化,您也可以这样做。你可以阅读更多关于它的内容。此外,我建议如果您想要纯文本文件格式,可以尝试使用ascii.ecsv,它的优点是可以输出额外的元数据,以便轻松地读回Astropy表:
>>> table.write(sys.stdout, format='ascii.ecsv')
# %ECSV 0.9
# ---
# datatype:
# - {name: J2000, datatype: float64}
# - {name: lat, datatype: float64}
# - {name: lon, datatype: float64}
# - {name: alt, datatype: float64}
# schema: astropy-2.0
J2000 lat lon alt
1085.01128806 48.5487129749 -144.175054697 264779.500823
2170.02257613 26.5068122883 -50.3805485685 262446.085716
3255.03386419 -28.7915478311 -1.6090285674 319661.817451
4340.04515225 -48.0536526356 91.5416828221 355717.274021
5425.05644032 0.084422392655 152.811717713 306129.02576
我要注意的另一件不相关的事情是,除了单个值之外,Astropy中的许多对象可以在整个数组上运行,这通常会更有效,特别是对于许多值。特别是,您有以下Python循环:
for i in range(propNum):
xyz = (myOrbitX[i], myOrbitY[i], myOrbitZ[i]) #Xyz coord for each prop. step
now = time.Time(myT[i]) #UTC time at each propagation step
cartrep = coord.CartesianRepresentation(*xyz, unit=u.m) #Add units of [m] to xyz
gcrs = coord.GCRS(cartrep, obstime=time.Time(myT[i])) #Let AstroPy know xyz is in GCRS
itrs = gcrs.transform_to(coord.ITRS(obstime=time.Time(myT[i]))) #Convert GCRS to ITRS
loc = coord.EarthLocation(*itrs.cartesian.xyz) #Get lat/lon/height from ITRS
lat.append(loc.lat.value) #Create latitude list
lon.append(loc.lon.value) #Create longitude list
alt.append(loc.height.value)
通过将它们视为坐标数组,可以完全重写它们,而无需显式循环。例如:
>>> times = time.Time(myT) # All the times, not just a single one
>>> cartrep = coord.CartesianRepresentation(orbitX, orbitY, orbitZ, unit=u.m) # Again, an array of coordinates
>>> gcrs = coord.GCRS(cartrep, obstime=times)
>>> itrs = gcrs.transform_to(coord.ITRS(obstime=ts))
>>> loc = coord.EarthLocation(*itrs.cartesian.xyz) # I'm not sure this is the most efficient way to do this but I'm not an expert on the coordinates package
通过这个,我们也可以得到所有的坐标数组。例如:
>>> loc.lat
<Latitude [ 48.54871297, 26.50681229,-28.79154783,-48.05365264,
0.08442239] deg>
所以这通常是处理大量坐标值的更有效的方法。类似地,在原始代码中转换myT时,您可以创建一个TimeDelta数组并将其添加到初始时间,而不是在所有时间偏移上循环
不幸的是,我不是轨道软件包方面的专家,但它似乎不像人们希望得到轨道上不同点的坐标那样容易。ISTM应该有。如何序列化标题?/这意味着什么?作为输出引用的文件是一个csv文件,其中包含一个标题,标题下有数据的列名。它是csv文件中的第一行。若要序列化它,您将使用WriteDataofileJ2000 Time、Lat、Lon、Alt\n之类的东西手动将该数据写入文件,然后通过编程在上面创建的数据列表中循环。作为旁注,我将对更大的数据集执行此操作,其中每个列表将具有约6000个值,而不是5个值,因此,我正在寻找最有效的方法。很清楚,您要问的是如何将数据列写成逗号分隔的值吗?您是否熟悉Numpy和/或Astropy的Table类?将Astropy表写入文件的最快方法是什么?您能否更具体一些?在代码量上最快还是在计算时间上最快?
>>> times = time.Time(myT) # All the times, not just a single one
>>> cartrep = coord.CartesianRepresentation(orbitX, orbitY, orbitZ, unit=u.m) # Again, an array of coordinates
>>> gcrs = coord.GCRS(cartrep, obstime=times)
>>> itrs = gcrs.transform_to(coord.ITRS(obstime=ts))
>>> loc = coord.EarthLocation(*itrs.cartesian.xyz) # I'm not sure this is the most efficient way to do this but I'm not an expert on the coordinates package
>>> loc.lat
<Latitude [ 48.54871297, 26.50681229,-28.79154783,-48.05365264,
0.08442239] deg>