2016-05-03 5 views
5

Ich lief in diesem Fehler beim Analysieren der wenigen Daten durch ParseDates von . Im folgenden Codefragment versuche ich Daten mit dem Format dd/mm/yy zu analysieren, was zu einer fehlerhaften Konvertierung führt. In einigen Fällen wird das Datumsfeld als Monat betrachtet und umgekehrt.pd.read_csv Datum/Monat Feld nicht korrekt analysieren, wenn parse_date = ['Spaltenname'] eingestellt

Um es einfach zu halten, in einigen Fällen dd/mm/yy erhalten konvertiert yyyy-dd-mm statt yyyy-mm-dd.

Fall 1:

04/10/96 is parsed as 1996-04-10, which is wrong. 

Fall 2:

15/07/97 is parsed as 1997-07-15, which is correct. 

Fall 3:

10/12/97 is parsed as 1997-10-12, which is wrong. 

Codebeispiel

import pandas as pd 

df = pd.read_csv('date_time.csv') 
print 'Data in csv:' 
print df 
print df['start_date'].dtypes 

print '----------------------------------------------' 

df = pd.read_csv('date_time.csv', parse_dates = ['start_date']) 
print 'Data after parsing:' 
print df 
print df['start_date'].dtypes 

Stromausgang

---------------------- 
Data in csv: 
---------------------- 
    start_date 
0 04/10/96 
1 15/07/97 
2 10/12/97 
3 06/03/99 
4  //1994 
5 /02/1967 
object 
---------------------- 
Data after parsing: 
---------------------- 
    start_date 
0 1996-04-10 
1 1997-07-15 
2 1997-10-12 
3 1999-06-03 
4 1994-01-01 
5 1967-02-01 
datetime64[ns] 

Erwartete Ausgabe

---------------------- 
Data in csv: 
---------------------- 
    start_date 
0 04/10/96 
1 15/07/97 
2 10/12/97 
3 06/03/99 
4  //1994 
5 /02/1967 
object 
---------------------- 
Data after parsing: 
---------------------- 
    start_date 

0 1996-10-04 
1 1997-07-15 
2 1997-12-10 
3 1999-03-06 
4 1994-01-01 
5 1967-02-01 
datetime64[ns] 

Mehr Kommentare:

I date_parser oder pandas.to_datetime() geben Sie das richtige Format für das Datum verwenden könnte. Aber in meinem Fall habe ich einige Datumsfelder wie ['//1997', '/02/1967'] für die ich ['01/01/1997','01/02/1967'] konvertieren muss. Die parse_dates hilft mir bei der Konvertierung dieser Art von Datumsfeldern in das erwartete Format, ohne dass ich eine zusätzliche Codezeile schreiben muss.

Gibt es dafür eine Lösung?

Bug [email protected]: https://github.com/pydata/pandas/issues/13063

+0

Haben Sie auf die neueste Version 0.18 von Pandas Aktualisierung versuchen? Ist das Problem immer noch da? –

+0

Haben Sie versucht, 'infer_datetime_format' auf' True' zu ​​setzen? – IanS

+1

Ich habe genau das gleiche Problem! Meine vorübergehende Lösung bestand darin, die Werte aus einer Excel-Datei (anstelle von CSV) zu lesen, wobei die Daten gemäß den lokalen Einstellungen des Systems analysiert werden, aber ich weiß, dass dies keine Lösung ist, die für die meisten Entwickler geeignet ist. Sie erhalten korrekte Daten, wenn der Tag> 12 ist, da Pandas erkennen, dass es kein Monatswert sein kann. – Shovalt

Antwort

3

In Version Pandas 0.18.0 Sie Parameter hinzufügen können dayfirst=True und dann funktioniert es:

import pandas as pd 
import io 

temp=u"""start_date 
04/10/96 
15/07/97 
10/12/97 
06/03/99 
//1994 
/02/1967 
""" 
#after testing replace io.StringIO(temp) to filename 
df = pd.read_csv(io.StringIO(temp), parse_dates = ['start_date'], dayfirst=True) 
    start_date 
0 1996-10-04 
1 1997-07-15 
2 1997-12-10 
3 1999-03-06 
4 1994-01-01 
5 1967-02-01 

Eine andere Lösung:

Sie können mit to_datetime mit unterschiedlichen Parametern Parsen format und errors='coerce' und dann combine_first:

date1 = pd.to_datetime(df['start_date'], format='%d/%m/%y', errors='coerce') 
print date1 
0 1996-10-04 
1 1997-07-15 
2 1997-12-10 
3 1999-03-06 
4   NaT 
5   NaT 
Name: start_date, dtype: datetime64[ns] 

date2 = pd.to_datetime(df['start_date'], format='/%m/%Y', errors='coerce') 
print date2 
0   NaT 
1   NaT 
2   NaT 
3   NaT 
4   NaT 
5 1967-02-01 
Name: start_date, dtype: datetime64[ns] 

date3 = pd.to_datetime(df['start_date'], format='//%Y', errors='coerce') 
print date3 
0   NaT 
1   NaT 
2   NaT 
3   NaT 
4 1994-01-01 
5   NaT 
Name: start_date, dtype: datetime64[ns] 
print date1.combine_first(date2).combine_first(date3) 
0 1996-10-04 
1 1997-07-15 
2 1997-12-10 
3 1999-03-06 
4 1994-01-01 
5 1967-02-01 
Name: start_date, dtype: datetime64[ns] 
+0

Danke @jezrael. Das ist cool. :) Ich schätze Ihre Bemühungen. Ich war mir nicht bewusst "DayFirst = True". Aber ich verstehe nicht, warum es einen anderen Parameter geben muss, um das richtige Datumsformat zu erhalten. Wäre es nicht besser, wenn 'parse_dates' es richtig verarbeiten könnte? –

+0

Harte Frage, ich denke 'Ajcr' als Entwickler von' Pandas' kann besser erklären. Aber ich denke, es geht um Leistung. – jezrael

Verwandte Themen