我有一段代码使用Skyfield计算一些卫星和行星的位置。为清楚起见,我使用 Pandas DataFrame 作为位置和相应时刻的容器。我想让计算并行,但总是得到同样的错误:TypeError: can't pickle Satrec objects
。测试了不同的并行器,例如 Dask、pandarallel、swifter 和 Pool.map()。
要并行化的一段代码示例:
def get_sun_position(self, row):
t = self.ts.utc(row["Date"]) # from skyfield
pos = self.earth.at(t).observe(self.sun).apparent().position.m # from skyfield, error is here
return pos
def get_sat_position(self, row):
t = self.ts.utc(row["Date"]) # from skyfield
pos = self.sat.at(t).position.m # from skyfield, error is here
return pos
def get_positions(self):
self.df["sat_pos"] = self.df.swifter.apply(self.get_sat_position, axis=1) # all the parallelization goes here
self.df["sun_pos"] = self.df.swifter.apply(self.get_sun_position, axis=1) # and here
# the same implementation but using dask
# self.df["sat_pos"] = dd.from_pandas(self.df, npartitions=4*cpu_count())\
# .map_partitions(lambda df : df.apply(lambda row : self.get_sat_position(row),axis=1))\
# .compute(scheduler='processes')
# self.df["sun_pos"] = dd.from_pandas(self.df, npartitions=4*cpu_count())\
# .map_partitions(lambda df : df.apply(lambda row : self.get_sun_position(row),axis=1))\
# .compute(scheduler='processes')
为了让 Dask 避免 Pickle,我尝试像这样手动 设置序列化serializers=['dask', 'pickle']
,但没有帮助。
据我了解,Skyfield 使用包含Satrec 类的 sgp4。
我想知道是否有某种方法可以并行化它.apply()
。或者也许我根本不应该尝试使用 Skyfield 函数进行并行处理?