2015-05-12 24 views
6

Ich benutze derzeit Python versucht, eine Datetime-Spalte in 2, eine für Date und eine für die Zeit zu teilen und haben auch die Spalte richtig formatiert.Formatieren von Datetime-Variablen geben fehlende Zeitwerte als 00:00:00. Unter Verwendung von Python

ORIGINAL DATASET

INCIDENT_DATE 
12/31/2006 11:20:00 PM 
12/31/2006 11:30:00 PM 
01/01/2007 00:25 
01/01/2007 00:10 
12/31/2006 11:30:00 AM 
01/01/2007 00:05 
01/01/2007 00:01 
12/31/2006 4:45:00 PM 
12/31/2006 11:50:00 PM 
**01/01/2007** 

* I 2 Codes verwendet haben, eine die Säule und den anderen zu formatieren, die sie spaltet. Doch nach dem Formatieren der Säule wurden geben fehlende Zeitwert 00.00.00 Wert, hier eine Zeit für 12 midnight.See angibt, unter

nach der Formatierung

2006-12-31 23:20:00 
2006-12-31 23:30:00 
2007-01-01 00:25:00 
2007-01-01 00:10:00 
2006-12-31 11:30:00 
2007-01-01 00:05:00 
2007-01-01 00:01:00 
2006-12-31 16:45:00 
2006-12-31 23:50:00 
**2007-01-01 00:00:00** 

Codes verwendet:

## Format datetime column 
crimeall['INCIDENT_DATE'] = pd.DatetimeIndex(crimeall['INCIDENT_DATE']) 

##Split DateTime column 
crimeall['TIME'],crimeall['DATE']= crimeall['INCIDENT_DATE'].apply(lambda x:x.time()), crimeall['INCIDENT_DATE'].apply(lambda x:x.date()) 

Gibt es einen Weg, dies zu tun, ohne dass der fehlende Zeitwert auf 00:00:00 gesetzt ist? Ist es möglich, diese fehlenden Werte während der Formatierung von datetime als Nan aufzuzeichnen?

Irgendwelche Gedanken darüber, wie ich eine formatierte Datetime erreichen kann, die die fehlenden Zeitwerte als NaN zeigt.

WAS ICH MAG IT LIKE Hoffnung

2006-12-31 23:20:00 
2006-12-31 23:30:00 
2007-01-01 00:25:00 
2007-01-01 00:10:00 
2006-12-31 11:30:00 
2007-01-01 00:05:00 
2007-01-01 00:01:00 
2006-12-31 16:45:00 
2006-12-31 23:50:00 
**2007-01-01 NaN** 

aussieht, dass es eine Möglichkeit, dies zu tun bekommen ist.

+0

Leider können Sie Ihre Frage bearbeiten, wie ich verstehe nicht, was das '**' sind.Kannst du auch deine echten rohen Eingabedaten posten, wenn du eine aktuelle Version von Pandas verwendest, dann solltest du in der Lage sein, wenn 'INCIDENT_DATE' bereits ein Datetime dtype ist, um 'crimeall [' TIME '], crimeall [' DATE '] zu tun = crimeall ['INCIDENT_DATE'] .dt.time, crimeall ['INCIDENT_DATE']. dt.date' – EdChum

+0

Wenn ich Ihre Frage richtig verstehe, ist Ihr Problem hier, dass Ihre Datumszeichenfolgen ein inkonsistentes Format haben, wenn Sie also einen Datetimeindex erstellen oder verwenden Sie 'pd.to_datetime' und dann einen fehlenden Zeitabschnitt (oder einen entsprechenden Datumsabschnitt), wird ein Standardwert geliefert. Sie können die' 00: 00: 00' durch 'NaT' ersetzen. – EdChum

+1

Aber es ist problematisch anzunehmen' 00: 00: 00' ist 'NaT', weil es sehr gut sein könnte. Herauszufinden, welche Werte gültig sind, muss ** vor ** Umwandlung in Datetime erfolgen. – JohnE

Antwort

0

Ich glaube nicht, dass es eine Möglichkeit ist, eine Datetime-Spalte wie zu haben, die Teil gültig und Teil NaN ist. Beachten Sie, dass eine datetime im Wesentlichen ein Format über einer Ganzzahl ist und eine Ganzzahl nicht halbgültig und halb fehlend sein kann (ein wenig mehr dazu unten).

Wie auch immer, ich würde nur eine neue Spalte für die Zeit als NaNs enthält. Beginnend mit der folgenden, wo ‚raw_dt‘ Ihre Rohdaten und ‚formatted_dt‘ eine richtige Datumzeit ist:

    raw_dt  formatted_dt 
0 12/31/2006 11:20:00 PM 2006-12-31 23:20:00 
1 12/31/2006 11:30:00 PM 2006-12-31 23:30:00 
... 
7 12/31/2006 4:45:00 PM 2006-12-31 16:45:00 
8 12/31/2006 11:50:00 PM 2006-12-31 23:50:00 
9    01/01/2007 2007-01-01 00:00:00 

ich eine Maske schaffen würde, etwa so:

df['valid_time'] = df.raw_dt.str.contains(':') 

die funktionieren sollte gut hier und Sie könnten eine Regex verwenden, wenn Sie etwas anspruchsvolleres brauchen. Dann erstellen Sie eine neue Zeitspalte.

df['time'] = df.ix[df['valid_time'],'formatted_dt'].dt.time 

        raw_dt  formatted_dt valid_time  time 
0 12/31/2006 11:20:00 PM 2006-12-31 23:20:00  True 23:20:00 
1 12/31/2006 11:30:00 PM 2006-12-31 23:30:00  True 23:30:00 
... 
7 12/31/2006 4:45:00 PM 2006-12-31 16:45:00  True 16:45:00 
8 12/31/2006 11:50:00 PM 2006-12-31 23:50:00  True 23:50:00 
9    01/01/2007 2007-01-01 00:00:00  False  NaN 

Von dort können Sie jedoch formatieren Sie mögen, zum Beispiel:

df.formatted_dt.dt.date.map(str) + df.time.map(str).str.rjust(9) 

0 2006-12-31 23:20:00 
1 2006-12-31 23:30:00 
... 
7 2006-12-31 16:45:00 
8 2006-12-31 23:50:00 
9 2007-01-01  nan 

kurz zu erweitern, was ein Datetime ist, werfen Sie einen Blick here und beachten Sie, dass Sie dies als ein flüchtiger Blick tun können was Datetime wirklich ist (Nanosekunden seit 1. Januar 1970):

df.formatted_dt.astype(np.int64) 

0 1167607200000000000 
1 1167607800000000000 
... 
7 1167583500000000000 
8 1167609000000000000 
9 1167609600000000000 
+0

Tausend Dank . Das hat wirklich gut funktioniert .... – Nerine

1

Hinzufügen ambiguous =‘NaT’ zu pd.DatetimeIndex. Wenn das nicht funktioniert, können Sie immer die Werte Patch etwas mit wie

crimeall['TIME'] = [np.NaN if t.isoformat()=='00:00:00' else t for t in crimeall['TIME']] 
+0

Hallo EdChurn und Ed Smith. Vielen Dank für Ihre Kommentare und Entschuldigung für ein wenig unklar, ich bin neu in Python & Pandas. Sie haben Recht, dass die Datumszeichenfolgen inkonsistent sind und dass beim Erstellen des datetimeindex Standardwerte (fehlende Werte) als 00:00:00 angegeben werden. Ich kann diese nicht durch NaTs nachher ersetzen, da ich auch Echtzeitwerte von 00:00:00 habe. Ich werde sie auch auf "Datum" und "Zeit" aufteilen, wenn das einen Unterschied machen könnte. Das "**" sollte nur auf die besondere Instanz aufmerksam machen. Entschuldigen Sie das Durcheinander. Nochmals vielen Dank für Ihre Hilfe. – Nerine

+0

Das ** verweist auch auf die Spalte für die Zeitangabe, in der die Uhrzeit fehlt. – Nerine

+0

Nicht sehr elegant, aber wenn Sie mit einer String-Spalte beginnen, können Sie in einem ersten Schritt eine Variable mit dem Wert 1 erstellen, wenn nur das Datum angegeben wird, zB: 'crimeall ['HOUR_MISSING'] = crimeall ['INCIDENT_DATE']. Apply (Lambda x: 1 wenn re.match ('^ [0-9] {2}/[0-9] {2}/[0-9] {4} $', x) sonst 0) ' – etna

Verwandte Themen