2013-07-04 11 views
58

Oggi sono rimasto sorpreso positivamente dal fatto che, durante la lettura dei dati da un file di dati (per esempio) panda è in grado di riconoscere i tipi di valori:I panda possono riconoscere automaticamente le date?

df = pandas.read_csv('test.dat', delimiter=r"\s+", names=['col1','col2','col3']) 

Ad esempio può essere controllato in questo modo:

for i, r in df.iterrows(): 
    print type(r['col1']), type(r['col2']), type(r['col3']) 

In particolare interi, i float e le stringhe sono stati riconosciuti correttamente. Tuttavia, ho una colonna che ha date nel seguente formato: 2013-6-4. Queste date sono state riconosciute come stringhe (non come oggetti data di Python). C'è un modo per "imparare" i panda alle date riconosciute?

risposta

138

È necessario aggiungere parse_dates=True o parse_dates=['column name'] durante la lettura, in genere è sufficiente per analizzarlo magicamente. Ma ci sono sempre strani formati che devono essere definiti manualmente. In tal caso è anche possibile aggiungere una funzione di analisi della data, che è il modo più flessibile possibile.

Supponiamo di avere una colonna 'datetime' con la stringa, quindi:

dateparse = lambda x: pd.datetime.strptime(x, '%Y-%m-%d %H:%M:%S') 

df = pd.read_csv(infile, parse_dates=['datetime'], date_parser=dateparse) 

In questo modo si può anche combinare più colonne in una singola colonna datetime, questo si fonde un 'data' e di un 'tempo' colonna in una singola colonna 'datetime':

dateparse = lambda x: pd.datetime.strptime(x, '%Y-%m-%d %H:%M:%S') 

df = pd.read_csv(infile, parse_dates={'datetime': ['date', 'time']}, date_parser=dateparse) 
+1

Non ha funzionato per me, ho ricevuto il seguente errore: 'TypeError: strptime() argomento 1 deve essere str, non float' –

+2

Ho ricevuto questo errore perché c'erano nan nel mio frame di dati. –

+0

puoi aggiungere un elemento che contiene anche il materiale non analizzabile o NaN o/N. perché sembra che questo parser salti l'intera colonna se qualcosa del genere è presente – Amir

10

pandas metodo read_csv è ottimo per le date di analisi. La documentazione completa a http://pandas.pydata.org/pandas-docs/stable/generated/pandas.io.parsers.read_csv.html

si può anche avere le varie parti della data in colonne diverse e passare il parametro:

parse_dates : boolean, list of ints or names, list of lists, or dict 
If True -> try parsing the index. If [1, 2, 3] -> try parsing columns 1, 2, 3 each as a 
separate date column. If [[1, 3]] -> combine columns 1 and 3 and parse as a single date 
column. {‘foo’ : [1, 3]} -> parse columns 1, 3 as date and call result ‘foo’ 

Il rilevamento di default di date grandi opere, ma sembra essere sbilanciata verso formati di data del Nord America . Se vivi altrove potresti occasionalmente essere catturato dai risultati. Per quanto posso ricordare, 1/6/2000 significa il 6 gennaio negli Stati Uniti rispetto al 1 giugno in cui vivo. È abbastanza intelligente da farli oscillare se vengono usate date come il 23/6/2000. Probabilmente è più sicuro rimanere con le variazioni della data di AAAAMMGD. Mi scuso con gli sviluppatori di panda, ma non l'ho ancora testato con date locali di recente.

è possibile utilizzare il parametro date_parser per passare una funzione per la conversione del formato.

date_parser : function 
Function to use for converting a sequence of string columns to an array of datetime 
instances. The default uses dateutil.parser.parser to do the conversion. 
+0

vedere la domanda è stata risposta mentre stavo scrivendo la mia risposta .. cancellerà la mia risposta in un giorno come @Rutger più direttamente risponde alla domanda. Mantenendoci qui, ma così perché ho avuto altre intuizioni che potrebbero essere utili – Joop

+0

Basta tenerlo, è una buona risposta pure. Una piccola ridondanza non fa male. :) –

+1

Per favore, non cancellare la risposta. Avere qualche altro aspetto coperto o altra formulazione (formulazione) potrebbe essere utile. – Roman

10

Forse l'interfaccia panda è cambiato da @Rutger rispose, ma nella versione che sto utilizzando (0.15.2), la funzione date_parser riceve un elenco di date, invece di un singolo valore. In questo caso, il suo codice dovrebbe essere aggiornato in questo modo:

dateparse = lambda dates: [pd.datetime.strptime(d, '%Y-%m-%d %H:%M:%S') for d in dates] 

df = pd.read_csv(infile, parse_dates=['datetime'], date_parser=dateparse) 
3

Sì - secondo il pandas.read_csvdocumentation:

Note: A fast-path exists for iso8601-formatted dates.

Così, se il CSV ha una colonna chiamata datetime e le date si presenta come 2013-01-01T01:01 per esempio, l'esecuzione di questo renderà i panda (sono su v0.19.2) prendere la data e l'ora automaticamente:

df = pd.read_csv('test.csv', parse_dates=['datetime'])

Si noti che è necessario passare esplicitamente parse_dates, non funziona a meno.

Verificare con:

df.dtypes

Si dovrebbe vedere il tipo di dati della colonna è datetime64[ns]

+0

Penso che tu abbia frainteso la domanda. L'utente è curioso di sapere se l'opzione potrebbe essere abilitata per il suo formato di stringa. –

+0

@AryaMcCarthy umm, vuole sostanzialmente che la data venga riconosciuta correttamente, quindi sto menzionando come può trasformare i dati di origine in modo che sia naturalmente riconosciuto dai panda. In nessun posto menziona che non può cambiare il formato dei dati di origine. – Gaurav

+0

Tuttavia, questa è una soluzione bella e semplice! Grazie per la condivisione! :) –

0

si potrebbe usare pandas.to_datetime() come consigliato nella documentazione per pandas.read_csv():

If a column or index contains an unparseable date, the entire column or index will be returned unaltered as an object data type. For non-standard datetime parsing, use pd.to_datetime after pd.read_csv .

Demo :

>>> D = {'date': '2013-6-4'} 
>>> df = pd.DataFrame(D, index=[0]) 
>>> df 
     date 
0 2013-6-4 
>>> df.dtypes 
date object 
dtype: object 
>>> df['date'] = pd.to_datetime(df.date, format='%Y-%m-%d') 
>>> df 
     date 
0 2013-06-04 
>>> df.dtypes 
date datetime64[ns] 
dtype: object 
1

Quando si uniscono due colonne in una singola colonna datetime, la risposta accettata genera un errore (versione pandas 0.20.3), poiché le colonne vengono inviate separatamente alla funzione date_parser.

le seguenti opere:

def dateparse(d,t): 
    dt = d + " " + t 
    return pd.datetime.strptime(dt, '%d/%m/%Y %H:%M:%S') 

df = pd.read_csv(infile, parse_dates={'datetime': ['date', 'time']}, date_parser=dateparse) 
0

df = pd.read_csv ("/ home/Manoj/Desktop/train_aWnotuB.csv", parse_dates = [ 'DateTime'])

Caratteristiche = lista (map (lambda x: [xhour, x.day, x.weekday(), x.month, x.year], df ['DateTime']))

+1

Benvenuti in SO. A meno che non aggiunga qualcosa di nuovo alla soluzione, si prega di astenersi dall'aggiungere nuove risposte quando esiste una risposta accettata. – ext

Problemi correlati