如何使用特定的dtype填充现有的numpy数组 [英] How to populate an existing numpy array with specific dtype

查看:162
本文介绍了如何使用特定的dtype填充现有的numpy数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们说我有一些固定的dtype的初始numpy数组:

Let's say that I have this initial numpy array with some fixed dtype:

array = numpy.array([(1, 'a'), (2, 'b')],
                    numpy.dtype([('idfield',numpy.int32),
                                 ('textfield', '|S256')]))

现在我需要在for循环中填充此数组,所以我要这样做

Now I need to populate this array in a for loop so I do that

for val in value:
    array = np.append(array, np.array([(val[0],val[1])],numpy.dtype([('idfield',numpy.int32),
                                                                     ('textfield', '|S256')])),axis=0)

它可以工作,但实际上看起来并不好!我需要在for循环中重新指定dtype,即使逻辑上我要使用相同的dtype填充数组也是如此.

It works but it really doesn't looks good ! I need to re-specified the dtype in the for loop, even if it's logic that i'm going to use the same dtype to populate my array.

您知道实现此操作的更简单方法吗?

Do you know a simpler way to achieve this operation ?

推荐答案

np.appendnp.concatenate

def append(arr, values, axis=None):
    arr = asanyarray(arr)
    if axis is None:
        if arr.ndim != 1:
            arr = arr.ravel()
        values = ravel(values)
        axis = arr.ndim-1
    return concatenate((arr, values), axis=axis)

In [89]: dt = np.dtype('U5,int')
In [90]: arr = np.array([('one',1)], dtype=dt)
In [91]: np.append(arr, ('two',2))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-91-bc17d9ad4a77> in <module>()
----> 1 np.append(arr, ('two',2))
 ...
-> 5166     return concatenate((arr, values), axis=axis)

TypeError: invalid type promotion

在这种情况下会

In [92]: np.ravel(('two',2))
Out[92]: array(['two', '2'], dtype='<U3')

将元组转换为2个元素的字符串dtype数组.现在,concatenate尝试将dt的数组与U3数组联接,但不能. append中没有任何内容使用arr.dtype作为将values转换为数组的基础.您需要自己做. numpy只能做很多事情来推断您的意图. :)

turning the tuple into a 2 element string dtype array. Now concatenate tries to join an array of dt with the U3 array, and it can't. There's nothing in the append uses the arr.dtype as the basis for turning values into an array. You need to do that yourself. numpy can only do so much to infer you intentions. :)

因此,如果您指定common dtype,它将起作用:

So if you specify common the dtype it works:

In [93]: np.append(arr, np.array(('two',2),dt))
Out[93]: array([('one', 1), ('two', 2)], dtype=[('f0', '<U5'), ('f1', '<i4')])

我不喜欢append,因为新用户经常滥用它.通常,他们将其视为列表附加克隆,但不是.

I dislike append because new users often misuse it. Usually they think of it as a list append clone, which it is not.

但是它确实有一个优势-它提升了0d输入的尺寸:

But it does have one advantage - it promotes the dimensions of 0d inputs:

In [94]: np.concatenate([arr, np.array(('two',2),dt)])
...
ValueError: all the input arrays must have same number of dimensions

使第二个数组1d起作用:

Making the 2nd array 1d works:

In [95]: np.concatenate([arr, np.array([('two',2)],dt)])
Out[95]: array([('one', 1), ('two', 2)], dtype=[('f0', '<U5'), ('f1', '<i4')])

append隐藏concatenate所需的尺寸调整.

append hides the dimensional adjustment that concatenate needs.

但是在可能的情况下,最好创建一个数组列表(或元组)并只执行一次concatenate:

But where possible it is better to create a list of arrays (or tuples) and do concatenate just once:

In [96]: alist = [('one',1),('two',2),('three',3)]
In [97]: ll = [np.array([x],dt) for x in alist]
In [98]: ll
Out[98]: 
[array([('one', 1)], dtype=[('f0', '<U5'), ('f1', '<i4')]),
 array([('two', 2)], dtype=[('f0', '<U5'), ('f1', '<i4')]),
 array([('three', 3)], dtype=[('f0', '<U5'), ('f1', '<i4')])]

In [100]: np.concatenate(ll)
Out[100]: 
array([('one', 1), ('two', 2), ('three', 3)],
      dtype=[('f0', '<U5'), ('f1', '<i4')])

但是直接从元组列表中创建数组会更好:

But making the array directly from a list of tuples is even better:

In [101]: np.array(alist, dt)
Out[101]: 
array([('one', 1), ('two', 2), ('three', 3)],
      dtype=[('f0', '<U5'), ('f1', '<i4')])

这篇关于如何使用特定的dtype填充现有的numpy数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆