web-dev-qa-db-fra.com

Les pandas Python convertissent efficacement l’heure en heure de l’heure via l’accesseur dt

J'ai une base de données avec quelques (centaines de) millions de lignes. Et je veux convertir date/heure en horodatage efficacement. Comment puis-je le faire?

Mon échantillon df:

df = pd.DataFrame(index=pd.DatetimeIndex(start=dt.datetime(2016,1,1,0,0,1),
    end=dt.datetime(2016,1,2,0,0,1), freq='H'))\
    .reset_index().rename(columns={'index':'datetime'})

df.head()

             datetime
0 2016-01-01 00:00:01
1 2016-01-01 01:00:01
2 2016-01-01 02:00:01
3 2016-01-01 03:00:01
4 2016-01-01 04:00:01

Maintenant, je convertis date/heure en horodatage valeur par valeur avec .apply(), mais cela prend beaucoup de temps (quelques heures) si j'ai quelques centaines de millions de lignes:

df['ts'] = df[['datetime']].apply(lambda x: x[0].timestamp(), axis=1).astype(int)

df.head()

             datetime          ts
0 2016-01-01 00:00:01  1451602801
1 2016-01-01 01:00:01  1451606401
2 2016-01-01 02:00:01  1451610001
3 2016-01-01 03:00:01  1451613601
4 2016-01-01 04:00:01  1451617201

Le résultat ci-dessus est ce que je veux.

Si j'essaie d'utiliser l'accesseur .dt de pandas.Series, le message d'erreur suivant s'affiche:

df['ts'] = df['datetime'].dt.timestamp

AttributeError: l'objet 'DatetimeProperties' n'a pas d'attribut 'horodatage'

Si j'essaie de créer par exemple. les parties de date de datetime avec l'accesseur .dt, alors il est beaucoup plus rapide que d'utiliser .apply():

df['date'] = df['datetime'].dt.date

df.head()

             datetime          ts        date
0 2016-01-01 00:00:01  1451602801  2016-01-01
1 2016-01-01 01:00:01  1451606401  2016-01-01
2 2016-01-01 02:00:01  1451610001  2016-01-01
3 2016-01-01 03:00:01  1451613601  2016-01-01
4 2016-01-01 04:00:01  1451617201  2016-01-01

Je veux quelque chose de similaire avec les horodatages ...

Mais je ne comprends pas vraiment la documentation officielle: elle parle de " Conversion en horodatages " mais je n'y vois aucun horodatage; il parle simplement de la conversion en date/heure avec pd.to_datetime() mais pas en horodatage ...

Le constructeur pandas.Timestamp ne fonctionne pas non plus (retourne avec l'erreur ci-dessous):

df['ts2'] = pd.Timestamp(df['datetime'])

TypeError: impossible de convertir une entrée en horodatage

pandas.Series.to_timestamp fait aussi quelque chose de totalement différent de ce que je veux:

df['ts3'] = df['datetime'].to_timestamp

df.head()

             datetime          ts                                                ts3
0 2016-01-01 00:00:01  1451602801  <bound method Series.to_timestamp of 0    2016...
1 2016-01-01 01:00:01  1451606401  <bound method Series.to_timestamp of 0    2016...
2 2016-01-01 02:00:01  1451610001  <bound method Series.to_timestamp of 0    2016...
3 2016-01-01 03:00:01  1451613601  <bound method Series.to_timestamp of 0    2016...
4 2016-01-01 04:00:01  1451617201  <bound method Series.to_timestamp of 0    2016...

Je vous remercie!!

14
ragesz

Je pense que vous devez d'abord convertir numpy array par values et transiter en int64 - la sortie est en ns, il est donc nécessaire de diviser par 10 ** 9:

df['ts'] = df.datetime.values.astype(np.int64) // 10 ** 9
print (df)
              datetime          ts
0  2016-01-01 00:00:01  1451606401
1  2016-01-01 01:00:01  1451610001
2  2016-01-01 02:00:01  1451613601
3  2016-01-01 03:00:01  1451617201
4  2016-01-01 04:00:01  1451620801
5  2016-01-01 05:00:01  1451624401
6  2016-01-01 06:00:01  1451628001
7  2016-01-01 07:00:01  1451631601
8  2016-01-01 08:00:01  1451635201
9  2016-01-01 09:00:01  1451638801
10 2016-01-01 10:00:01  1451642401
11 2016-01-01 11:00:01  1451646001
12 2016-01-01 12:00:01  1451649601
13 2016-01-01 13:00:01  1451653201
14 2016-01-01 14:00:01  1451656801
15 2016-01-01 15:00:01  1451660401
16 2016-01-01 16:00:01  1451664001
17 2016-01-01 17:00:01  1451667601
18 2016-01-01 18:00:01  1451671201
19 2016-01-01 19:00:01  1451674801
20 2016-01-01 20:00:01  1451678401
21 2016-01-01 21:00:01  1451682001
22 2016-01-01 22:00:01  1451685601
23 2016-01-01 23:00:01  1451689201
24 2016-01-02 00:00:01  1451692801

to_timestamp est utilisé pour convertir de période en index date/heure .

19
jezrael

Si vous ne voulez pas utiliser numpy, vous pouvez utiliser des conversions de pandas purs.

df['ts'] = pd.to_timedelta(df['datetime'], unit='ns').dt.total_seconds().astype(int)
0
Jozef Cechovsky

Il existe également une autre méthode pour ce faire, qui utilise l'attribut "caché" de DatetimeIndex appelé asi8, qui crée un horodatage entier.

pd.DatetimeIndex(df.datetime).asi8

Wes McKinney a suggéré cette question dans cette question de flux de pile liée de manière tangentielle liée ici

0
BCR