如何更改numpy recarray的某些列的dtype?

时间:2012-03-30 19:38:23

标签: python pandas numpy

假设我有一个重新排列如下:

import numpy as np

# example data from @unutbu's answer
recs = [('Bill', '31', 260.0), ('Fred', 15, '145.0')]
r = np.rec.fromrecords(recs, formats = 'S30,i2,f4', names = 'name, age, weight')

print(r)
# [('Bill', 31, 260.0) ('Fred', 15, 145.0)]

说我想将某些列转换为浮点数。我该怎么做呢?我应该改为ndarray并将它们重新组合成一个重新组合吗?

3 个答案:

答案 0 :(得分:16)

以下是使用astype执行转换的示例:

import numpy as np
recs = [('Bill', '31', 260.0), ('Fred', 15, '145.0')]
r = np.rec.fromrecords(recs, formats = 'S30,i2,f4', names = 'name, age, weight')
print(r)
# [('Bill', 31, 260.0) ('Fred', 15, 145.0)]

age是dtype <i2

print(r.dtype)
# [('name', '|S30'), ('age', '<i2'), ('weight', '<f4')]

我们可以使用<f4

将其更改为astype
r = r.astype([('name', '|S30'), ('age', '<f4'), ('weight', '<f4')])
print(r)
# [('Bill', 31.0, 260.0) ('Fred', 15.0, 145.0)]

答案 1 :(得分:13)

基本上有两个步骤。我的绊脚石是找到如何修改现有的dtype。我就这样做了:

# change dtype by making a whole new array
dt = data.dtype
dt = dt.descr # this is now a modifiable list, can't modify numpy.dtype
# change the type of the first col:
dt[0] = (dt[0][0], 'float64')
dt = numpy.dtype(dt)
# data = numpy.array(data, dtype=dt) # option 1
data = data.astype(dt)

答案 2 :(得分:0)

这里是对现有答案的较小改进,并扩展了一些情况,您希望根据dtype而不是列名进行更改(例如,将所有浮点数更改为整数)。

首先,您可以使用listcomp来提高简洁性和可读性:

col       = 'age'
new_dtype = 'float64'

r.astype( [ (col, new_dtype) if d[0] == col else d for d in r.dtype.descr ] )

# rec.array([(b'Bill', 31.0, 260.0), (b'Fred', 15.0, 145.0)], 
#           dtype=[('name', 'S30'), ('age', '<f8'), ('weight', '<f4')])

第二,您可以扩展此语法以处理要将所有浮点数更改为整数的情况(反之亦然)。例如,如果您要将32位或64位浮点数更改为64位整数,则可以执行以下操作:

old_dtype = ['<f4', '<f8']
new_dtype = 'int64'

r.astype( [ (d[0], new_dtype) if d[1] in old_dtype else d for d in r.dtype.descr ] )

# rec.array([(b'Bill', 31, 260), (b'Fred', 15, 145)], 
#           dtype=[('name', 'S30'), ('age', '<i2'), ('weight', '<i8')])

请注意,astype有一个可选的强制转换参数,默认为unsafe,因此您可能需要指定casting='safe'以避免在将浮点数转换为整数时意外丢失精度:

r.astype( [ (d[0], new_dtype) if d[1] in old_dtype else d for d in r.dtype.descr ],
          casting='safe' )

有关casting和其他选项的更多信息,请参考numpy documentation on astype

还要注意,对于将浮点数更改为整数(反之亦然)的一般情况,您可能更愿意使用np.issubdtype检查常规数字类型,而不是针对多个特定的dtypes。