2012-11-29 1 views
6

Mi piacerebbe semplicemente creare una serie numerica di dimensioni (N, m) che ha solo la prima colonna composta da numeri interi e il resto di default float. In modo che, se inizializzato a zero dovrebbe essere risultato:come (semplicemente) creare un numero intero e float array numpy misto

array([[ 0, 0., 0., 0., 0.], 
     [ 0, 0., 0., 0., 0.], 
     [ 0, 0., 0., 0., 0.], 
     [ 0, 0., 0., 0., 0.], 
     [ 0, 0., 0., 0., 0.]]) 

Tutti i tentativi che ho fatto mi ritornano alcuni sotto-elementi tupla quando si cerca di creare un array come strutturato.

+0

Per curiosità, perché dovresti averne bisogno? – Rambatino

+0

Immaginate di dover memorizzare alcuni dati misti, dove 1 campo è intero (cioè uno stato discretizzato), e gli altri sono reali. – gluuke

+0

Ma cosa stai facendo con questi dati? Quando è 1! = 1,0 problematico? – Rambatino

risposta

13

Si potrebbe usare un array con dtype = object:

>>> arr = np.ndarray((10,4),dtype = object) 
>>> arr[:,0] = int(10) 
>>> arr[:,1:] = float(10) 
>>> arr 
array([[10, 10.0, 10.0, 10.0], 
     [10, 10.0, 10.0, 10.0], 
     [10, 10.0, 10.0, 10.0], 
     [10, 10.0, 10.0, 10.0], 
     [10, 10.0, 10.0, 10.0], 
     [10, 10.0, 10.0, 10.0], 
     [10, 10.0, 10.0, 10.0], 
     [10, 10.0, 10.0, 10.0], 
     [10, 10.0, 10.0, 10.0], 
     [10, 10.0, 10.0, 10.0]], dtype=object) 

noti che si ottiene il giusto comportamento quando si fa l'aritmetica.

>>> arr/3 
array([[3, 3.33333333333, 3.33333333333, 3.33333333333], 
     [3, 3.33333333333, 3.33333333333, 3.33333333333], 
     [3, 3.33333333333, 3.33333333333, 3.33333333333], 
     [3, 3.33333333333, 3.33333333333, 3.33333333333], 
     [3, 3.33333333333, 3.33333333333, 3.33333333333], 
     [3, 3.33333333333, 3.33333333333, 3.33333333333], 
     [3, 3.33333333333, 3.33333333333, 3.33333333333], 
     [3, 3.33333333333, 3.33333333333, 3.33333333333], 
     [3, 3.33333333333, 3.33333333333, 3.33333333333], 
     [3, 3.33333333333, 3.33333333333, 3.33333333333]], dtype=object) 

Oppure si potrebbe usare un numpy.recarray:

>>> import numpy as np 
>>> arr = np.recarray(10,dtype=[('x',int),('y',float,4)]) 
>>> arr[:] = 0 
>>> arr 
rec.array([(0, array([ 0., 0., 0., 0.])), (0, array([ 0., 0., 0., 0.])), 
      (0, array([ 0., 0., 0., 0.])), (0, array([ 0., 0., 0., 0.])), 
      (0, array([ 0., 0., 0., 0.])), (0, array([ 0., 0., 0., 0.])), 
      (0, array([ 0., 0., 0., 0.])), (0, array([ 0., 0., 0., 0.])), 
      (0, array([ 0., 0., 0., 0.])), (0, array([ 0., 0., 0., 0.]))], 
    dtype=[('x', '<i4'), ('y', '<f8', (4,))]) 
>>> arr['x'] 
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) 
>>> arr['y'] 
array([[ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.]]) 

Se avete bisogno di fare aritmetica su tutti i valori, si dovrà eseguire l'operazione su ogni campo separatamente, per esempio

>>> arr['x'] += 2 
>>> arr['y'] += 2 
0

Leggere questa nella documentazione NumPy, che indica tutti i membri devono essere dello stesso tipo

scopo principale di NumPy è la matrice multidimensionale omogenea. È una tabella di elementi (in genere numeri), tutti dello stesso tipo, indicizzati da una tupla di numeri interi positivi.

2

Anche se mi viene in mente un sacco di motivi per cui non si dovrebbe essere voler fare questo, in primo luogo, non è per me giudicare, e io odio quando la gente cerca di sminuire il valore della mia hack'n'dirty hack.

La motivazione è quella di utilizzare dtype=object. Dal momento che tutto in Python è un oggetto, è possibile combinare tipi numerici pur mantenendo l'omogeneità all'interno di un array. Suggerisco quanto segue, ma ovviamente puoi adattarti alle tue esigenze:

import numpy 

rows = 5 
a = numpy.zeros((rows,5)).astype(object) 
a[:,0] = a[:,0].astype(int) 
print a 

[[0 0.0 0.0 0.0 0.0] 
[0 0.0 0.0 0.0 0.0] 
[0 0.0 0.0 0.0 0.0] 
[0 0.0 0.0 0.0 0.0] 
[0 0.0 0.0 0.0 0.0]]