web-dev-qa-db-fra.com

Ajouter des jours aux dates dans la trame de données

Je suis bloquée en ce moment. Je suis sûr que je manque quelque chose de simple, mais comment faire avancer une série de dates de x unités? Dans mon cas plus spécifique, je veux ajouter 180 jours à une série de dates dans une trame de données.

Voici ce que j'ai jusqu'à présent:

import pandas, numpy, StringIO, datetime


txt = '''ID,DATE
002691c9cec109e64558848f1358ac16,2003-08-13 00:00:00
002691c9cec109e64558848f1358ac16,2003-08-13 00:00:00
0088f218a1f00e0fe1b94919dc68ec33,2006-05-07 00:00:00
0088f218a1f00e0fe1b94919dc68ec33,2006-06-03 00:00:00
00d34668025906d55ae2e529615f530a,2006-03-09 00:00:00
00d34668025906d55ae2e529615f530a,2006-03-09 00:00:00
0101d3286dfbd58642a7527ecbddb92e,2007-10-13 00:00:00
0101d3286dfbd58642a7527ecbddb92e,2007-10-27 00:00:00
0103bd73af66e5a44f7867c0bb2203cc,2001-02-01 00:00:00
0103bd73af66e5a44f7867c0bb2203cc,2008-01-20 00:00:00
'''
df = pandas.read_csv(StringIO.StringIO(txt))
df = df.sort('DATE')
df.DATE = pandas.to_datetime(df.DATE)
df['X_DATE'] = df['DATE'].shift(180, freq=pandas.datetools.Day)

Ce code génère une erreur de type. Pour référence j'utilise:

Python 2.7.4 Pandas '0.12.0.dev-6e7c4d6' Numpy '1.7.1'

17
BigHandsome

Si je vous comprends bien, vous ne voulez pas vraiment shift, vous voulez simplement faire une nouvelle colonne à côté de la DATE existante qui est 180 jours après. Dans ce cas, vous pouvez utiliser timedelta:

>>> from datetime import timedelta
>>> df.head()
                                 ID                DATE
8  0103bd73af66e5a44f7867c0bb2203cc 2001-02-01 00:00:00
0  002691c9cec109e64558848f1358ac16 2003-08-13 00:00:00
1  002691c9cec109e64558848f1358ac16 2003-08-13 00:00:00
5  00d34668025906d55ae2e529615f530a 2006-03-09 00:00:00
4  00d34668025906d55ae2e529615f530a 2006-03-09 00:00:00
>>> df["X_DATE"] = df["DATE"] + timedelta(days=180)
>>> df.head()
                                 ID                DATE              X_DATE
8  0103bd73af66e5a44f7867c0bb2203cc 2001-02-01 00:00:00 2001-07-31 00:00:00
0  002691c9cec109e64558848f1358ac16 2003-08-13 00:00:00 2004-02-09 00:00:00
1  002691c9cec109e64558848f1358ac16 2003-08-13 00:00:00 2004-02-09 00:00:00
5  00d34668025906d55ae2e529615f530a 2006-03-09 00:00:00 2006-09-05 00:00:00
4  00d34668025906d55ae2e529615f530a 2006-03-09 00:00:00 2006-09-05 00:00:00

Est-ce que ça aide?

40
DSM

Vous pouvez utiliser pd.DateOffset. Ce qui semble être plus rapide que timedelta.

In [930]: df['x_DATE'] = df['DATE'] + pd.DateOffset(days=180)

In [931]: df
Out[931]:
                                 ID       DATE     x_DATE
8  0103bd73af66e5a44f7867c0bb2203cc 2001-02-01 2001-07-31
0  002691c9cec109e64558848f1358ac16 2003-08-13 2004-02-09
1  002691c9cec109e64558848f1358ac16 2003-08-13 2004-02-09
4  00d34668025906d55ae2e529615f530a 2006-03-09 2006-09-05
5  00d34668025906d55ae2e529615f530a 2006-03-09 2006-09-05
2  0088f218a1f00e0fe1b94919dc68ec33 2006-05-07 2006-11-03
3  0088f218a1f00e0fe1b94919dc68ec33 2006-06-03 2006-11-30
6  0101d3286dfbd58642a7527ecbddb92e 2007-10-13 2008-04-10
7  0101d3286dfbd58642a7527ecbddb92e 2007-10-27 2008-04-24
9  0103bd73af66e5a44f7867c0bb2203cc 2008-01-20 2008-07-18

Timings

Moyen

In [948]: df.shape
Out[948]: (10000, 3)

In [950]: %timeit df['DATE'] + pd.DateOffset(days=180)
1000 loops, best of 3: 1.51 ms per loop

In [949]: %timeit df['DATE'] + timedelta(days=180)
100 loops, best of 3: 2.71 ms per loop

Grand

In [952]: df.shape
Out[952]: (100000, 3)

In [953]: %timeit df['DATE'] + pd.DateOffset(days=180)
100 loops, best of 3: 4.16 ms per loop

In [955]: %timeit df['DATE'] + timedelta(days=180)
10 loops, best of 3: 20 ms per loop
21
Zero

Pour les futurs lecteurs, si vous souhaitez modifier différentes lignes de montants différents, vous devrez utiliser Pandas TimedeltaIndex à la place pour passer une série de timedeltas.

Par exemple, je pourrais vouloir déplacer mes données vers la période de rapport la plus proche et chaque enregistrement pourrait avoir commencé un jour différent de la semaine.

import pandas as pd
days_to_shift = pd.TimedeltaIndex(6 - launch_df['launch_dt'].dt.dayofweek)
launch_df['launch_dt'] = launch_df['launch_dt'] + days_to_shift
13
dreyco676