Połącz kolumny Data i godzina za pomocą pand w języku Python

113

Mam ramkę danych pandy z następującymi kolumnami;

Date              Time
01-06-2013      23:00:00
02-06-2013      01:00:00
02-06-2013      21:00:00
02-06-2013      22:00:00
02-06-2013      23:00:00
03-06-2013      01:00:00
03-06-2013      21:00:00
03-06-2013      22:00:00
03-06-2013      23:00:00
04-06-2013      01:00:00

Jak połączyć dane [„Data”] i [„Czas”], aby uzyskać następujące informacje? Czy można to zrobić za pomocą pd.to_datetime?

Date
01-06-2013 23:00:00
02-06-2013 01:00:00
02-06-2013 21:00:00
02-06-2013 22:00:00
02-06-2013 23:00:00
03-06-2013 01:00:00
03-06-2013 21:00:00
03-06-2013 22:00:00
03-06-2013 23:00:00
04-06-2013 01:00:00
Richie
źródło
Dzięki za wszystkie odpowiedzi. Wypróbowałem większość z nich, ale nadal dodam te informacje o datach i godzinach jako część większej ramki danych. Kolumna data i godzina wyświetla tylko datę, a informacje o czasie nie są wyświetlane. Czy powinniśmy rozumieć, że czas jest tam ukryty, czy jest usuwany?
karthikeyan

Odpowiedzi:

169

Warto wspomnieć, że być może byłeś w stanie przeczytać to bezpośrednio, np. Jeśli read_csvużywałeś parse_dates=[['Date', 'Time']].

Zakładając, że są to tylko ciągi znaków, możesz po prostu dodać je razem (ze spacją), umożliwiając zastosowanie to_datetime:

In [11]: df['Date'] + ' ' + df['Time']
Out[11]:
0    01-06-2013 23:00:00
1    02-06-2013 01:00:00
2    02-06-2013 21:00:00
3    02-06-2013 22:00:00
4    02-06-2013 23:00:00
5    03-06-2013 01:00:00
6    03-06-2013 21:00:00
7    03-06-2013 22:00:00
8    03-06-2013 23:00:00
9    04-06-2013 01:00:00
dtype: object

In [12]: pd.to_datetime(df['Date'] + ' ' + df['Time'])
Out[12]:
0   2013-01-06 23:00:00
1   2013-02-06 01:00:00
2   2013-02-06 21:00:00
3   2013-02-06 22:00:00
4   2013-02-06 23:00:00
5   2013-03-06 01:00:00
6   2013-03-06 21:00:00
7   2013-03-06 22:00:00
8   2013-03-06 23:00:00
9   2013-04-06 01:00:00
dtype: datetime64[ns]

Uwaga: zaskakująco (dla mnie) działa to dobrze w przypadku konwersji NaN na NaT, ale warto się martwić, że konwersja (być może przy użyciu raiseargumentu).

Andy Hayden
źródło
6
Nie wiem o funkcję automatycznego skojarzonej, i współpracuje z wieloma wpisami też, jak: parse_dates=[['Start date', 'Start time'], ['End date', 'End time']]). Pandy <3
5agado
43

Zaakceptowana odpowiedź działa w przypadku kolumn typu danych string. Dla kompletności: natknąłem się na to pytanie, szukając, jak to zrobić, gdy kolumny mają typy danych: datę i godzinę.

df.apply(lambda r : pd.datetime.combine(r['date_column_name'],r['time_column_name']),1)
jka.ne
źródło
2
Nie mogę znaleźć nic na temat typu timew pandach. Mam raczej a timedelta(i datetime) w takim przypadku wystarczy je dodać, zobacz moją odpowiedź
toto_tico
Kiedy „pd.read_excel” jest kolumną programu Excel, którą program Excel identyfikuje jako „Czas”, pandy automatycznie odczytują ją również jako „Czas”, bez konieczności stosowania żadnego argumentu analizy. Dzięki za to rozwiązanie. +1
Saeed,
1
Tylko uwaga, od pandy 1.0.0 pd.datetime jest przestarzałe i sugeruje się, aby datetimezamiast tego jawnie zaimportować moduł.
CopOnTheRun
17

Możesz użyć tego do scalenia daty i godziny w tej samej kolumnie Dataframe.

import pandas as pd    
data_file = 'data.csv' #path of your file

Czytanie pliku .csv z połączonymi kolumnami Date_Time:

data = pd.read_csv(data_file, parse_dates=[['Date', 'Time']]) 

Możesz użyć tej linii, aby zachować również obie inne kolumny.

data.set_index(['Date', 'Time'], drop=False)
MK Rana
źródło
1
Możesz także użyć niestandardowego date_parser, na przykładparser = lambda date: pd.datetime.strptime(date, '%d-%b-%y %H:%M:%S')
Serendipity
11

Możesz rzutować kolumny, jeśli typy są różne (datetime i timestamp lub str) i użyć to_datetime:

df.loc[:,'Date'] = pd.to_datetime(df.Date.astype(str)+' '+df.Time.astype(str))

Wynik:

0   2013-01-06 23:00:00
1   2013-02-06 01:00:00
2   2013-02-06 21:00:00
3   2013-02-06 22:00:00
4   2013-02-06 23:00:00
5   2013-03-06 01:00:00
6   2013-03-06 21:00:00
7   2013-03-06 22:00:00
8   2013-03-06 23:00:00
9   2013-04-06 01:00:00

Najlepsza,

Chris PERE
źródło
10

Nie mam wystarczającej reputacji, aby komentować jka.ne, więc:

Musiałem poprawić wiersz jka.ne, aby działał:

df.apply(lambda r : pd.datetime.combine(r['date_column_name'],r['time_column_name']).time(),1)

To może pomóc innym.

Przetestowałem też inne podejście, używając replacezamiast combine:

def combine_date_time(df, datecol, timecol):
    return df.apply(lambda row: row[datecol].replace(
                                hour=row[timecol].hour,
                                minute=row[timecol].minute),
                    axis=1)

co w przypadku PO byłoby:

combine_date_time(df, 'Date', 'Time')

Ustawiłem czas dla obu podejść dla stosunkowo dużego zbioru danych (> 500 000 wierszy) i oba mają podobne środowiska uruchomieniowe, ale użycie combinejest szybsze (59s dla replacevs 50s dla combine).

jabellcu
źródło
5

Odpowiedź naprawdę zależy od typów twoich kolumn . W moim przypadku miałem datetimei timedelta.

> df[['Date','Time']].dtypes
Date     datetime64[ns]
Time    timedelta64[ns]

Jeśli tak jest w Twoim przypadku, wystarczy dodać kolumny:

> df['Date'] + df['Time']
toto_tico
źródło
Przyjęta odpowiedź zakłada ciągi: „Zakładając, że są to tylko ciągi znaków, można je po prostu dodać razem (ze spacją)” . Moje odpowiedzi są dla datetimei timedelta. Główna odpowiedź w jakiś sposób wskazuje, że kolumny były łańcuchami, a może to była po prostu odpowiedź, która zadziałała w przypadku tego, który opublikował pytanie.
toto_tico
4

Możesz również przekonwertować na datetimebez konkatenacji ciągów, łącząc datetimei timedeltaobiekty. W połączeniu z pd.DataFrame.popmożesz jednocześnie usunąć serię źródłową:

df['DateTime'] = pd.to_datetime(df.pop('Date')) + pd.to_timedelta(df.pop('Time'))

print(df)

             DateTime
0 2013-01-06 23:00:00
1 2013-02-06 01:00:00
2 2013-02-06 21:00:00
3 2013-02-06 22:00:00
4 2013-02-06 23:00:00
5 2013-03-06 01:00:00
6 2013-03-06 21:00:00
7 2013-03-06 22:00:00
8 2013-03-06 23:00:00
9 2013-04-06 01:00:00

print(df.dtypes)

DateTime    datetime64[ns]
dtype: object
jpp
źródło
1
Świetne rozwiązanie ogólne! Miałem typ datetime date i typ str time i to zadziałało.
wróbel
3

Najpierw upewnij się, że masz odpowiednie typy danych:

df["Date"] = pd.to_datetime(df["Date"])
df["Time"] = pd.to_timedelta(df["Time"])

Następnie łatwo je łączysz:

df["DateTime"] = df["Date"] + df["Time"]
queise
źródło
2

Użyj combinefunkcji:

datetime.datetime.combine(date, time)
Stephen
źródło
2

Mój zestaw danych zawierał dane o rozdzielczości 1 sekundy przez kilka dni i analizowanie sugerowanymi tu metodami było bardzo wolne. Zamiast tego użyłem:

dates = pandas.to_datetime(df.Date, cache=True)
times = pandas.to_timedelta(df.Time)
datetimes  = dates + times

Zwróć uwagę, że użycie funkcji cache=Truesprawia, że ​​analizowanie dat jest bardzo wydajne, ponieważ w moich plikach jest tylko kilka unikalnych dat, co nie jest prawdą dla połączonej kolumny daty i godziny.

tgbrooks
źródło
To właśnie bym zrobił.
Yaakov Bressler
1

DANE:

<TICKER>, <PER>, <DATE>, <TIME> , <OPEN>, <HIGH>, <LOW>, <CLOSE>, <VOL> SPFB.RTS, 1, 20190103,100100 , 106580.0000000,107260.0000000,106570.0000000 , 107230,0000000, 3726

KOD:

data.columns = ['ticker', 'per', 'date', 'time', 'open', 'high', 'low', 'close', 'vol']    
data.datetime = pd.to_datetime(data.date.astype(str) + ' ' + data.time.astype(str), format='%Y%m%d %H%M%S')
hacknull
źródło