Combinez les colonnes de date et d'heure à l'aide de pandas python

113

J'ai un dataframe pandas avec les colonnes suivantes;

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

Comment combiner les données ['Date'] et les données ['Heure'] pour obtenir ce qui suit? Y a-t-il un moyen de le faire en utilisant 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
la source
Merci pour toutes les réponses. J'ai essayé la plupart d'entre eux mais toujours lorsque j'ajoute ces informations datetime dans le cadre d'un dataframe plus grand. La colonne datetime affiche uniquement la date et les informations d'heure ne sont pas affichées. Doit-on comprendre que le temps y est caché ou est-il supprimé?
karthikeyan

Réponses:

169

Il convient de mentionner que vous avez peut-être pu lire ceci directement, par exemple si vous utilisiez read_csvusing parse_dates=[['Date', 'Time']].

En supposant que ce ne sont que des chaînes, vous pouvez simplement les ajouter (avec un espace), ce qui vous permet d'appliquer 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]

Remarque: étonnamment (pour moi), cela fonctionne bien avec les NaN convertis en NaT, mais cela vaut la peine de s'inquiéter de la conversion (peut-être en utilisant l' raiseargument).

Andy Hayden
la source
6
Je ne savais pas sur la fonction de combinaison automatique, et il fonctionne avec des entrées multiples aussi, comme: parse_dates=[['Start date', 'Start time'], ['End date', 'End time']]). Pandas <3
août
43

La réponse acceptée fonctionne pour les colonnes de type de données string. Par souci d'exhaustivité: je rencontre cette question en cherchant comment faire cela lorsque les colonnes sont de types de données: date et heure.

df.apply(lambda r : pd.datetime.combine(r['date_column_name'],r['time_column_name']),1)
jka.ne
la source
2
Je ne trouve rien concernant le timedtype, chez les pandas. J'ai plutôt un timedelta(et un datetime) auquel cas il suffit de les ajouter, voir ma réponse
toto_tico
Quand je 'pd.read_excel' une colonne Excel qu'Excel identifie comme "Time", pandas la lit également automatiquement comme "Time" sans aucun argument d'analyse requis. Merci pour cette solution. +1
Saeed
1
Juste une note, depuis pandas 1.0.0 pd.datetime est obsolète et il est suggéré d'importer explicitement le datetimemodule à la place.
CopOnTheRun
17

Vous pouvez l'utiliser pour fusionner la date et l'heure dans la même colonne de dataframe.

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

Lecture du fichier .csv avec les colonnes fusionnées Date_Heure:

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

Vous pouvez également utiliser cette ligne pour conserver les deux autres colonnes.

data.set_index(['Date', 'Time'], drop=False)
MK Rana
la source
1
Vous pouvez également utiliser la personnalisation date_parser, par exempleparser = lambda date: pd.datetime.strptime(date, '%d-%b-%y %H:%M:%S')
Serendipity
11

Vous pouvez convertir les colonnes si les types sont différents (datetime et timestamp ou str) et utiliser to_datetime:

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

Résultat :

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

Meilleur,

Chris PERE
la source
10

Je n'ai pas assez de réputation pour commenter jka.ne donc:

J'ai dû modifier la ligne de jka.ne pour que cela fonctionne:

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

Cela pourrait aider les autres.

De plus, j'ai testé une approche différente, en utilisant replaceau lieu de 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)

ce qui dans le cas du PO serait:

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

J'ai chronométré les deux approches pour un ensemble de données relativement volumineux (> 500.000 lignes), et elles ont toutes les deux des durées d'exécution similaires, mais l'utilisation combineest plus rapide (59s pour replacevs 50s pour combine).

jabellcu
la source
5

La réponse dépend vraiment de ce que sont vos types de colonnes . Dans mon cas, j'avais datetimeet timedelta.

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

Si tel est votre cas, il vous suffit d'ajouter les colonnes:

> df['Date'] + df['Time']
toto_tico
la source
La réponse acceptée suppose des chaînes: "En supposant que ce ne sont que des chaînes, vous pouvez simplement les ajouter ensemble (avec un espace)" . Mes réponses sont pour datetimeet timedelta. La réponse principale consiste en quelque sorte à comprendre que les colonnes étaient des chaînes, ou peut-être que c'était juste la réponse qui a fonctionné pour celle qui a publié la question.
toto_tico
4

Vous pouvez également convertir en datetimesans concaténation de chaînes, en combinant datetimeet des timedeltaobjets. Combiné avec pd.DataFrame.pop, vous pouvez supprimer la série source simultanément:

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
la source
1
Excellente solution générale! J'avais la date de type datetime et l'heure de type str et cela a fonctionné.
moineau
3

Assurez-vous d'abord d'avoir les bons types de données:

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

Ensuite, vous les combinez facilement:

df["DateTime"] = df["Date"] + df["Time"]
queise
la source
2

Utilisez la combinefonction:

datetime.datetime.combine(date, time)
Stephen
la source
2

Mon ensemble de données avait des données de résolution d'une seconde pendant quelques jours et l'analyse par les méthodes suggérées ici était très lente. Au lieu de cela, j'ai utilisé:

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

Notez que l'utilisation de cache=Truerend l'analyse des dates très efficace car il n'y a que quelques dates uniques dans mes fichiers, ce qui n'est pas vrai pour une colonne de date et d'heure combinée.

tgbrooks
la source
C'est ce que je ferais.
Yaakov Bressler
1

LES DONNÉES:

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

CODE:

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
la source