我尝试将astropy表的列表转换为astropy表的numpy数组。在第一个实例中我尝试np.asarray(list)
np.array(list)
但astropy表列表与列表转换为内部numpy ndarray。
的例子:
t = Table({'a': [1,2,3], 'b':[4,5,6]})
t2 = Table({'a': [7,8,9], 'b':[10,11,12]})
mylist = [t1, t2]
print(mylist)
输出为:
[<Table length=3>
a b
int64 int64
----- -----
1 4
2 5
3 6,
<Table length=3>
a b
int64 int64
----- -----
7 10
8 11
9 12]
然后如果我应用np.array()
输出是:
array([[(1, 4), (2, 5), (3, 6)],
[(7, 10), (8, 11), (9, 12)]], dtype=[('a', '<i8'), ('b', '<i8')])
但我想要以下内容:
array([<Table length=3>
a b
int64 int64
----- -----
1 4
2 5
3 6,
<Table length=3>
a b
int64 int64
----- -----
7 10
8 11
9 12])
我的实际解决方案是:
if isinstance(mylist, list):
myarray = np.empty(len(mylist), dtype='object')
for i in range(len(myarray)):
myarray[i] = mylist[i]
else:
myarray = mylist
return myarray
它可以工作,但我认为可能有一些内置的东西在numpy中做到这一点,但我找不到它。
这看起来是Astropy表的限制,我认为这是一个bug: Astropy的表将防止强制转换为NumPy数组,因为这并不总是有效:在代码中有一个特定的检查,如果在尝试将表转换为NumPy数组时指定了dtype
,则会引发ValueError
。
当然,这里你是在处理一个列表。但是现在您遇到了两个问题:NumPy将尝试将列表转换为数组,并对每个单独的元素应用转换。您可以获得没有指定dtype
的2D数组,或者再次获得指定dtype
的ValueError
:
ValueError: Datatype coercion is not allowed
错误(我认为)是Astropy检查dtype
任何,而不是None
。因此,即使object
作为dtype也会引发此错误,我不确定它是否应该。
因此,在我看来,你的变通方法是好的。不理想,但它可以完成工作,基本上只有2-3行代码。
既然你提到了布尔索引,那么考虑以下几点,同时将所有内容保存在列表中(我认为这是更好的选择:NumPy数组实际上是用于数字的,而不是那么多对象):
indices = [True, False, True, False]
my_list = [....] # list of tables
selection = [item for item, index in zip(my_list, indices) if index] # filter all True values
或对于编号索引:
indices = [1, 3, 5, 6]
my_list = [....] # list of tables
selection = [my_list[i] for i in indices]
与NumPy索引相同的行数,除非您的列表增长到数千(数百万)个元素,否则您不会注意到性能差异。(如果它确实增长到数百万个元素,您可能需要重新考虑您的数据结构,这需要在代码的其他地方进行更多的重写。)