将 astropy Table 列表转换为 astropy Table 的 numpy 数组
Convert a list of astropy Table in a numpy array of astropy Table
我尝试在 astropy Table 的 numpy 数组中转换一个 astropy Table 列表。在第一个实例中,我尝试了 np.asarray(list)
和 np.array(list)
但是列表中的星形 table 被转换为 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 Table 的限制,我认为这是一个错误:Astropy 的 Table 会阻止对 NumPy 数组的强制转换,因为这并不总是有效:有一个如果在尝试将 table 转换为 NumPy 数组时指定了 dtype
,则会在代码中进行特定检查,如果指定了 ValueError
。
当然,这里你处理的是一个列表。但是现在您 运行 遇到了两个问题:NumPy 将尝试将列表转换为数组,并对每个单独的元素应用转换。您要么得到一个没有指定 dtype
的二维数组,要么再次得到指定了 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 索引相同,除非您的列表增长到数千(百万)个元素,否则您不会注意到性能差异。 (如果它确实增长到数百万个元素,您可能需要重新考虑您的数据结构,这需要在代码的其他地方进行更多重写。)
我尝试在 astropy Table 的 numpy 数组中转换一个 astropy Table 列表。在第一个实例中,我尝试了 np.asarray(list)
和 np.array(list)
但是列表中的星形 table 被转换为 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 Table 的限制,我认为这是一个错误:Astropy 的 Table 会阻止对 NumPy 数组的强制转换,因为这并不总是有效:有一个如果在尝试将 table 转换为 NumPy 数组时指定了 dtype
,则会在代码中进行特定检查,如果指定了 ValueError
。
当然,这里你处理的是一个列表。但是现在您 运行 遇到了两个问题:NumPy 将尝试将列表转换为数组,并对每个单独的元素应用转换。您要么得到一个没有指定 dtype
的二维数组,要么再次得到指定了 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 索引相同,除非您的列表增长到数千(百万)个元素,否则您不会注意到性能差异。 (如果它确实增长到数百万个元素,您可能需要重新考虑您的数据结构,这需要在代码的其他地方进行更多重写。)