在Python NumPy数组中指定每个对象的dtype
下面的代码片段创建了一个“典型的测试数组”,这个数组的目的是用来测试我程序中的各种功能。有没有办法,或者说是否可能改变数组中元素的类型呢?
import numpy as np
import random
from random import uniform, randrange, choice
# ... bunch of silly code ...
def gen_test_array( ua, low_inc, med_inc, num_of_vectors ):
#typical_array = [ zone_id, ua, inc, veh, pop, hh, with_se, is_cbd, re, se=0, oe]
typical_array = np.zeros( shape = ( num_of_vectors, 11 ) )
for i in range( 0, num_of_vectors ):
typical_array[i] = [i, int( ua ), uniform( low_inc / 2, med_inc * 2 ), uniform( 0, 6 ),
randrange( 100, 5000 ), randrange( 100, 500 ),
choice( [True, False] ), choice( [True, False] ),
randrange( 100, 5000 ), randrange( 100, 5000 ),
randrange( 100, 5000 ) ]
return typical_array
2 个回答
4
引用一下NumPy参考手册第一章的第一句话:
NumPy provides an N-dimensional array type, the ndarray, which describes a collection of “items” of the same type.
这就是说,数组里的每一个元素都必须是同一种类型。和普通的Python列表相比,这样的限制虽然有点不灵活,但它让数组的操作速度更快:在运行循环的时候,不需要检查每个元素的类型。
9
在numpy中,处理这个问题的方法是使用结构化数组。
不过,在很多情况下,如果你要处理不同类型的数据,简单的python列表会是一个更好的选择。(虽然在这个回答写的时候还不太普及,但其实pandas.DataFrame
在这种情况下是最理想的选择。)
不管怎样,你上面给出的例子在“普通”的numpy数组中也能完美运行。你只需要把你给出的例子中的所有内容都变成浮点数就可以了。(除了两列是浮点数,其他的看起来都是整数... 布尔值也可以很容易地用整数表示。)
不过,为了说明如何使用结构化数据类型...
import numpy as np
ua = 5 # No idea what "ua" is in your code above...
low_inc, med_inc = 0.5, 2.0 # Again, no idea what these are...
num = 100
num_fields = 11
# Use more descriptive names than "col1"! I'm just generating the names as placeholders
dtype = {'names':['col%i'%i for i in range(num_fields)],
'formats':2*[np.int] + 2*[np.float] + 2*[np.int] + 2*[np.bool] + 3*[np.int]}
data = np.zeros(num, dtype=dtype)
# Being rather verbose...
data['col0'] = np.arange(num, dtype=np.int)
data['col1'] = int(ua) * np.ones(num)
data['col2'] = np.random.uniform(low_inc / 2, med_inc * 2, num)
data['col3'] = np.random.uniform(0, 6, num)
data['col4'] = np.random.randint(100, 5000, num)
data['col5'] = np.random.randint(100, 500, num)
data['col6'] = np.random.randint(0, 2, num).astype(np.bool)
data['col7'] = np.random.randint(0, 2, num).astype(np.bool)
data['col8'] = np.random.randint(100, 5000, num)
data['col9'] = np.random.randint(100, 5000, num)
data['col10'] = np.random.randint(100, 5000, num)
print data
这将生成一个包含11个字段的100个元素的数组:
array([ (0, 5, 2.0886534380436226, 3.0111285613794276, 3476, 117, False, False, 4704, 4372, 4062),
(1, 5, 2.0977199579338115, 1.8687472941590277, 4635, 496, True, False, 4079, 4263, 3196),
...
...
(98, 5, 1.1682309811443277, 1.4100766819689299, 1213, 135, False, False, 1250, 2534, 1160),
(99, 5, 1.746554619056416, 5.210411489007637, 1387, 352, False, False, 3520, 3772, 3249)],
dtype=[('col0', '<i8'), ('col1', '<i8'), ('col2', '<f8'), ('col3', '<f8'), ('col4', '<i8'), ('col5', '<i8'), ('col6', '|b1'), ('col7', '|b1'), ('col8', '<i8'), ('col9', '<i8'), ('col10', '<i8')])