numpy 是否处理 dtype 错误的数组?

Does numpy handle arrays with dtype wrong?

以下代码片段

f_folds = 3
fold_quantities = np.array([(0, 0, 0)])
for i in np.arange(n_folds) + 1:
    fold_quantities = np.concatenate(
        (fold_quantities, [(i, 0, 0)])
    )
print(fold_quantities)

给我

array([[ 0,  0,  0],
       [ 1,  0,  0],
       [ 2,  0,  0],
       [ 3,  0,  0]])

除了指定 ndarray 的数据类型外什么都不改变

f_folds = 3
fold_quantities = np.array([(0, 0, 0)],
    dtype=[('index', int), ('#datapoints', 'int'), ('#pos_labels', 'int')])
for i in np.arange(n_folds) + 1:
    fold_quantities = np.concatenate(
        (fold_quantities, [(i, 0, 0)])
    )
print(fold_quantities)

它抛出一个错误

ValueError   Traceback (most recent call last)
<ipython-input-174-649369eed10a> in <module>
      5     fold_quantities = np.concatenate(
      6         (fold_quantities,
----> 7          [(i, 0, 0)])
      8     )
      9 print(fold_quantities)

<__array_function__ internals> in concatenate(*args, **kwargs)

ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 1 dimension(s) and the array at index 1 has 2 dimension(s)

这条消息似乎没有意义。数组维度没有改变。

应该如何处理?我想指定 dtype,因为我想根据带有 sorted(key=) 的单列对数组进行排序。

您的第一个数组应该使用列表追加或列表理解来制作。重复连接速度较慢

In [97]: np.array([[i,0,0] for i in range(4)])                                                 
Out[97]: 
array([[0, 0, 0],
   [1, 0, 0],
   [2, 0, 0],
   [3, 0, 0]])

复合数据类型:

In [100]: np.array([(i,0,0) for i in range(4)], dtype=dt)                                      
Out[100]: 
array([(0, 0, 0), (1, 0, 0), (2, 0, 0), (3, 0, 0)],
      dtype=[('index', '<i8'), ('#datapoints', '<i8'), ('#pos_labels', '<i8')])

注意使用 dt 和元组而不是列表。结构化数组的数据必须采用元组列表的形式(就像显示一样)。

随着dtype的变化,形状发生变化:

In [101]: _100.shape                                                                           
Out[101]: (4,)
In [102]: _97.shape                                                                            
Out[102]: (4, 3)

要将数组添加到结构化数组,它必须具有兼容的数据类型和形状:

In [104]: np.array([(4,0,0)],dt)                                                               
Out[104]: 
array([(4, 0, 0)],
      dtype=[('index', '<i8'), ('#datapoints', '<i8'), ('#pos_labels', '<i8')])

这是一个 dt 类型的 (1,) 数组。

In [105]: np.concatenate([_100, _104])                                                         
Out[105]: 
array([(0, 0, 0), (1, 0, 0), (2, 0, 0), (3, 0, 0), (4, 0, 0)],
      dtype=[('index', '<i8'), ('#datapoints', '<i8'), ('#pos_labels', '<i8')])
In [106]: _.shape                                                                              
Out[106]: (5,)

制作结构化数组的另一种方法 - 从具有正确 dtype 的数组列表开始:

In [107]: alist = [np.array((i,0,0),dt) for i in range(4)]                                     
In [108]: alist                                                                                
Out[108]: 
[array((0, 0, 0),
       dtype=[('index', '<i8'), ('#datapoints', '<i8'), ('#pos_labels', '<i8')]),
 array((1, 0, 0),
       dtype=[('index', '<i8'), ('#datapoints', '<i8'), ('#pos_labels', '<i8')]),
 array((2, 0, 0),
       dtype=[('index', '<i8'), ('#datapoints', '<i8'), ('#pos_labels', '<i8')]),
 array((3, 0, 0),
       dtype=[('index', '<i8'), ('#datapoints', '<i8'), ('#pos_labels', '<i8')])]

我使用 stack 加入它们,因为所有 3 个都有 0d 标量数组。

In [109]: np.stack(alist)                                                                      
Out[109]: 
array([(0, 0, 0), (1, 0, 0), (2, 0, 0), (3, 0, 0)],
      dtype=[('index', '<i8'), ('#datapoints', '<i8'), ('#pos_labels', '<i8')])