2010-09-16 10 views
6

El siguiente fragmento crea una "matriz de prueba típico", el propósito de esta matriz es poner a prueba una variedad de cosas en mi programa. ¿Hay alguna manera o incluso es posible cambiar el tipo de elementos en una matriz?especifique dtype de cada objeto en una matriz de pitón numpy

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 

Respuesta

8

La forma de hacerlo en numpy es usar structured array.

Sin embargo, en muchos casos en los que está utilizando datos heterogéneos, una simple lista de python es mucho mejor opción. (O, aunque no estaba ampliamente disponible cuando se escribió esta respuesta, un pandas.DataFrame es absolutamente ideal para este escenario.)

Independientemente, el ejemplo que proporcionó anteriormente funcionará perfectamente como una matriz numpy "normal". Puedes simplemente hacer flotar todo en el ejemplo que diste. (Todo lo que parece ser un entero, a excepción de dos columnas de flotadores ... Los Bools fácilmente pueden ser representados como enteros.)

Sin embargo, para ilustrar el uso de dtypes estructurados ...

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 

que produce una matriz de 100 elementos con 11 campos:

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')]) 
4

Citando la primera línea de capítulo 1 de the NumPy reference:

NumPy provides an N-dimensional array type, the ndarray, which describes a collection of “items” of the same type. 

Así que cada miembro de la matriz tiene que ser del mismo tipo. La pérdida de generalidad aquí, en comparación con las listas regulares de Python, es la compensación que permite operaciones de alta velocidad en matrices: los bucles se pueden ejecutar sin probar el tipo de cada miembro.

+0

¿hay alguna alternativa al uso de np.array? – dassouki

+1

¿Qué estás tratando de hacer exactamente? Pienso en numpy como acelerar las matemáticas: multiplicación de matrices, o tomar el coseno de un montón de entradas. Sin saber más acerca de lo que estás haciendo, todo lo que puedo sugerir es una lista regular de Python. – mtrw

Cuestiones relacionadas