我有一个辐射源的多波段目录(来自SourceExtractor,如果你愿意知道的话),我已经用以下形式读入了一个星座表:
Source # | FLUX_APER_BAND1 | FLUXERR_APER_BAND1 ... FLUX_APER_BANDN | FLUXERR_APER_BANDN
1 np.array(...) np.array(...) ... np.array(...) np.array(...)
...
FLUX_APER_BAND1
,FLUXERR_APER_BAND1
等中的数组各有14个元素,它们给出给定波段中给定源的光子数,距离中心的14个不同距离内。光源(光度测光)。我有一系列光圈(2,3,4,6,8,10,14,20,28,40,60,80,100和160像素),我想将14个样本插入一个(假设)计算其他一些光圈a
。
我可以遍历源代码,但目录中有超过3000个,并且这不是非常pythonic或非常有效(在8个波段中插入3000个对象需要一段时间)。有没有办法将同一列中的所有阵列同时插入相同的光圈?我尝试过简单地应用np.interp
,但提出了ValueError: object too deep for desired array
以及np.vectorize(np.interp)
,但是提出了ValueError: object of too small depth for desired array
。似乎聚合也应该可以在单个列的内容上进行,但我无法理解文档。
有人可以对此有所了解吗?提前谢谢!
答案 0 :(得分:2)
我不熟悉天文表的格式,但它看起来像是一个三维的numpy数组,带有源,带和光圈的轴。如果是这种情况,您可以使用scipy.interpolate.interp1d
。这是一个简单的例子。
In [51]: from scipy.interpolate import interp1d
制作一些样本数据。 "表" y
是3-D,形状为(2,3,14)。可以把它看作是包含2个源,3个波段和14个孔的计数的数组。
In [52]: x = np.array([2, 3, 4, 6, 8, 10, 14, 20, 28, 40, 60, 80, 100, 160])
In [53]: y = np.array([[x, 2*x, 3*x], [x**2, (x+1)**3/400, (x**1.5).astype(int)]])
In [54]: y
Out[54]:
array([[[ 2, 3, 4, 6, 8, 10, 14, 20, 28,
40, 60, 80, 100, 160],
[ 4, 6, 8, 12, 16, 20, 28, 40, 56,
80, 120, 160, 200, 320],
[ 6, 9, 12, 18, 24, 30, 42, 60, 84,
120, 180, 240, 300, 480]],
[[ 4, 9, 16, 36, 64, 100, 196, 400, 784,
1600, 3600, 6400, 10000, 25600],
[ 0, 0, 0, 0, 1, 3, 8, 23, 60,
172, 567, 1328, 2575, 10433],
[ 2, 5, 8, 14, 22, 31, 52, 89, 148,
252, 464, 715, 1000, 2023]]])
创建插补器。这默认创建一个线性插值器。 (查看不同插值器的docstring。另外,在调用interp1d
之前,您可能希望以适合线性插值的方式转换数据。)我使用axis=2
创建插值器光圈轴。 f
将是一个获取光圈值并返回形状为(2,3)的数组的函数。
In [55]: f = interp1d(x, y, axis=2)
看看几个y
切片。这些对应于孔径2和3(即x[0]
和x[1]
)。
In [56]: y[:,:,0]
Out[56]:
array([[2, 4, 6],
[4, 0, 2]])
In [57]: y[:,:,1]
Out[57]:
array([[3, 6, 9],
[9, 0, 5]])
使用插值器获取孔径2,2.5和3处的值。正如预期的那样,2和3处的值与y
中的值匹配。
In [58]: f(2)
Out[58]:
array([[ 2., 4., 6.],
[ 4., 0., 2.]])
In [59]: f(2.5)
Out[59]:
array([[ 2.5, 5. , 7.5],
[ 6.5, 0. , 3.5]])
In [60]: f(3)
Out[60]:
array([[ 3., 6., 9.],
[ 9., 0., 5.]])
答案 1 :(得分:1)
关于Pythonic,其关键方面是简单性,可读性和实用性。如果您的情况确实是一次性的(即您将进行几次而不是一百万次的3000 x 8插值),那么最快且最容易理解的解决方案将是简单的迭代Python循环。从你知道你的问题到你从代码中得到答案为止,我的意思是最快。
循环和调用函数24000次的开销在人类/天文学时间尺度上非常小,并且肯定比写入堆栈溢出帖子低得多。 : - )