2015-05-12 5 views
6

Obecnie używam pythona, który próbuje podzielić kolumnę datetime na 2, jedną dla daty i jedną dla czasu, a także poprawnie sformatować kolumnę.Formatowanie zmiennych datetime daje brakujące wartości czasu jako 00:00:00. Korzystanie z Pythona

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** 

* Użyłem 2 kody, jeden sformatować kolumnę, a drugi, że dzieli go. Jednak po formatowaniu kolumnę, brakujących wartości czasu dawali 00:00:00 wartość, tutaj wskazujący czas na 12 midnight.See poniżej

po formatowaniu

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** 

kodów stosowanych:

## 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()) 

Czy można to zrobić bez utraty wartości czasu ustawionej na 00:00:00? Czy podczas formatowania datetime można utracić te brakujące wartości jako Nan?

Wszelkie uwagi na temat tego, w jaki sposób mogę uzyskać sformatowaną datę i czas, pokazując brakujące wartości czasu jako NaN.

co chciałbym to wygladac

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** 

Mając nadzieję, że istnieje sposób, aby to zrobić.

+0

Możesz edytować swoje pytanie, ponieważ nie rozumiem, do czego służą "**".Możesz również zamieścić prawdziwe dane wejściowe, jeśli korzystasz z najnowszej wersji pandy, wtedy powinieneś być w stanie, jeśli "INCIDENT_DATE" jest już typem datetime, który po prostu robi 'crimeall ['TIME'], crimeall ['DATE'] = crimeall ['INCIDENT_DATE']. dt.time, crimeall ['INCIDENT_DATE']. dt.date' – EdChum

+0

Jeśli dobrze rozumiem twoje pytanie, twój problem polega na tym, że twoje ciągi dat mają niepoprawny format, więc kiedy tworzysz datetimeindex lub użyj 'pd.to_datetime', a następnie brakującą część czasu (lub porcję daty), dostarczona zostanie wartość domyślna. Możesz zastąpić' 00: 00: 00' przez 'NaT' później – EdChum

+1

Ale problematyczne jest założenie' 00: 00: 00' to 'NaT', ponieważ może być bardzo ważny. Ustalenie, które wartości są poprawne, należy wykonać ** przed ** konwersją do datetime. – JohnE

Odpowiedz

0

nie wierzą, że istnieje jakiś sposób, aby mieć kolumnę datetime-like, który jest częścią ważne i część NaN. Zauważ, że datetime jest zasadniczo formatem na szczycie liczby całkowitej, a liczba całkowita nie może być w połowie poprawna, a na pół brakująca (trochę więcej na tym poniżej).

W każdym razie, po prostu stworzyłem nową kolumnę na czas, niż zawiera NaN. Począwszy od następujących, gdzie „raw_dt” jest twoim surowe dane i „formatted_dt” jest właściwa datetime:

    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 

Chciałbym utworzyć maskę, coś takiego:

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

które powinny pracować dobrze tutaj i możesz użyć wyrażenia regularnego, jeśli potrzebujesz czegoś bardziej wyrafinowanego. Następnie utwórz nową kolumnę czasu.

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 

Stamtąd można formatować jednak chcesz, na przykład:

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 

Aby krótko rozwinąć na co datetime jest spojrzeć here i zauważ, że można to zrobić jak okiem na co to jest datetime (nano-sekundy od 1 stycznia 1970):

df.formatted_dt.astype(np.int64) 

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

Dzięki za milion . To działało naprawdę dobrze ... – Nerine

1

Dodaj ambiguous =‘NaT’ do pd.DatetimeIndex. Jeśli to nie pomoże, zawsze można załatać wartości za pomocą coś jak

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

Witaj EdChurn i Ed Smith. Dziękuję za komentarze i przepraszam za nieco niejasne, jestem nowy w python i pandy. Masz rację, że ciągi dat są niepowiązane i że podczas konstruowania datetime index, wartości domyślne (brakujące wartości) są podawane jako 00:00:00. Nie mogę ich zastąpić "NaT's po, ponieważ mam również wartości czasu rzeczywistego 00:00:00. Będę również dzielił je na "Date" i "Time", jeśli może to mieć znaczenie. "**" miało tylko zwrócić uwagę na konkretną instancję. Przepraszam za zamieszanie. Jeszcze raz dziękuję za pomoc. – Nerine

+0

Również ** odnosi się do kolumny czasu, w której brakuje czasu. – Nerine

+0

Niezbyt elegancka, ale jeśli zaczynasz od kolumny z ciągiem znaków, możesz utworzyć zmienną w pierwszym kroku z wartością 1, gdy podano tylko datę, np .: 'crimeall ['HOUR_MISSING'] = crimeall ['INCIDENT_DATE']. Apply (apply) lambda x: 1 if re.match ('^ [0-9] {2}/[0-9] {2}/[0-9] {4} $', x) else 0) ' – etna