Numpy hybrid type Matrix astype

时间:2015-05-09 15:29:44

标签: python numpy matrix

我试图投射一个我已定义的numpy矩阵:

    matrix = numpy.array([['name','23','45','1'],
                         ['name2','223','43','5'],
                         ['name3','12','33','2']])

导致:

array([['name1', '23', '45', '1'],
       ['name2', '223', '43', '5'],
       ['name3', '12', '33', '2']], 
      dtype='|S5')

我想命名并将矩阵的每一列投射到以下类型:

dt = numpy.dtype({'names':['name','x','y','n'],'formats': ['S10', 'S10', 'S10', 'S10']})

现在,我会考虑矩阵所有字符串,因为它不起作用,但是期望的是这样的格式'formats': ['S10', 'f3', 'f3', 'i'] 并做这样的事情:

matrix.astype(dtype=dt,casting='safe')

结果:

array([[('name', 'name', 'name', 'name'), ('23', '23', '23', '23'),
        ('45', '45', '45', '45'), ('1', '1', '1', '1')],
       [('name2', 'name2', 'name2', 'name2'), ('223', '223', '223', '223'),
        ('43', '43', '43', '43'), ('5', '5', '5', '5')],
       [('name3', 'name3', 'name3', 'name3'), ('12', '12', '12', '12'),
        ('33', '33', '33', '33'), ('2', '2', '2', '2')]], 
      dtype=[('name', 'S10'), ('x', 'S10'), ('y', 'S10'), ('n', 'S10')])

我错过了什么?如何使用numpy模块为每个矩阵列定义类型?

1 个答案:

答案 0 :(得分:0)

创建/填充结构化数组有点棘手。有各种各样的方法,但我认为最简单的方法是使用元组列表:

In [11]: np.array([tuple(row) for row in matrix], dtype=dt)
Out[11]: 
array([('name', '23', '45', '1'), 
       ('name2', '223', '43', '5'),
       ('name3', '12', '33', '2')], 
      dtype=[('name', 'S10'), ('x', 'S10'), ('y', 'S10'), ('n', 'S10')])

结果是1d数组,dtype字段替换原始2d数组的列。新数组的每个元素都具有相同的类型 - 由dt指定。

或者你可以创建一个所需dtype的空数组,然后逐行或逐字段填充它:

In [14]: arr = np.zeros((3,),dt)    
In [16]: arr[0]=tuple(matrix[0,:])  # tuple of row
In [17]: arr['name']=matrix[:,0]    # field

In [18]: arr
Out[18]: 
array([('name', '23', '45', '1'), 
       ('name2', '', '', ''),
       ('name3', '', '', '')], 
      dtype=[('name', 'S10'), ('x', 'S10'), ('y', 'S10'), ('n', 'S10')])

使用兼容的dt1view也可以使用

dt1 = numpy.dtype({'names':['name','x','y','n'],'formats': ['S5', 'S5', 'S5', 'S5']})
matrix.view(dt1)

这不会改变数据;它只是以不同的方式解释字节。

使用元组列表

可以轻松地将字符串转换为数字
In [40]: dt2 = numpy.dtype({'names':['name','x','y','n'],'formats': ['S5', 'f', 'f', 'i']})

In [41]: np.array([tuple(row) for row in matrix], dtype=dt2)Out[41]: 
array([('name', 23.0, 45.0, 1), 
       ('name2', 223.0, 43.0, 5),
       ('name3', 12.0, 33.0, 2)], 
      dtype=[('name', 'S5'), ('x', '<f4'), ('y', '<f4'), ('n', '<i4')])