2012-02-02 3 views
15

E 'possibile inizializzare un riepilogo numerico che manterrà le stringhe, senza conoscere prima la lunghezza delle stringhe?stringhe di ripetizione numpy di lunghezza variabile

Come un (forzato) Esempio:

mydf = np.empty((numrows,), dtype=[ ('file_name','STRING'), ('file_size_MB',float) ]) 

Il problema è che sto costruendo il mio recArray in anticipo popolato con le informazioni, e non necessariamente conosce la lunghezza massima di file_name in anticipo .

Tutti i miei tentativi risultato nel campo di stringa troncati:

>>> mydf = np.empty((2,), dtype=[('file_name',str),('file_size_mb',float)]) 
>>> mydf['file_name'][0]='foobarasdf.tif' 
>>> mydf['file_name'][1]='arghtidlsarbda.jpg' 
>>> mydf 
array([('', 6.9164002347457e-310), ('', 9.9413127e-317)], 
     dtype=[('file_name', 'S'), ('file_size_mb', '<f8')]) 
>>> mydf['file_name'] 
array(['f', 'a'], 
     dtype='|S1') 

(Per inciso, perché fa mydf['file_name'] show 'f' e 'a', mentre mydf spettacoli '' e ''?)

Allo stesso modo, se io inizializzo con il tipo di (diciamo) |S10 per file_name allora le cose si fanno troncata a lungo 10.

L'unica domanda simile che ho trovato è this one, ma questo calcu cancella la lunghezza della stringa appropriata a priori e quindi non è proprio la mia (non so nulla in anticipo).

Esiste un'alternativa diversa dall'initalizzazione dello file_name con (es.) |S9999999999999 (ovvero un limite superiore ridicolo)?

+0

questa è una buona domanda. lunghezza 0 corde in recarsie mi ha fatto strappare i capelli per mezz'ora! – Christoph

risposta

24

Invece di utilizzare il dtype STRING, è sempre possibile utilizzare object come dtype. Ciò consentirà di assegnare qualsiasi oggetto a un elemento dell'array, incluse le stringhe di lunghezza variabile Python. Ad esempio:

>>> import numpy as np 
>>> mydf = np.empty((2,), dtype=[('file_name',object),('file_size_mb',float)]) 
>>> mydf['file_name'][0]='foobarasdf.tif' 
>>> mydf['file_name'][1]='arghtidlsarbda.jpg' 
>>> mydf 
array([('foobarasdf.tif', 0.0), ('arghtidlsarbda.jpg', 0.0)], 
     dtype=[('file_name', '|O8'), ('file_size_mb', '<f8')]) 

È un contro lo spirito del concetto matrice di avere elementi di lunghezza variabile, ma questo è il più vicino si può ottenere. L'idea di una matrice è che gli elementi sono memorizzati in memoria con indirizzi di memoria ben definiti e regolarmente distanziati, che proibiscono elementi di lunghezza variabile. Memorizzando i puntatori a una stringa in una matrice, si può aggirare questa limitazione. (Questo è fondamentalmente ciò che fa l'esempio sopra.)

+0

grazie per quello - Sto solo spostandomi dal linguaggio R e fondamentalmente volevo un tipo di oggetto frame di dati, e questo funziona benissimo! –

+3

Commento in ritardo: se ci si sta spostando da R, considerare l'oggetto pandas.DataFrame, che dovrebbe sembrare molto familiare e gestire bene le stringhe. – mdurant