2017-10-08 5 views
1

J'ai un DataFrame de valeurs enregistrées et l'index défini sur DatetimeIndex. Une valeur est enregistrée environ toutes les 15 minutes.Comment un DataFrame peut-il être déplacé vers l'index temporel le plus proche de celui spécifié?

Je veux ajouter une nouvelle colonne qui est la différence fractionnaire de la valeur actuelle d'une valeur 24 heures auparavant. Puisque les valeurs sont enregistrées environ toutes les quinze minutes, je veux passer à l'index temporel le plus proche de 24 heures auparavant. Si je tente de faire exactement, je me retrouve avec beaucoup de NaN s:

df["value"]/df["value"].shift(freq = datetime.timedelta(days = -1)) 

Comment ce changement devrait être fait pour que celui spécifié le décalage est de l'indice de temps possible le plus proche? Existe-t-il une alternative, une façon plus simple de penser à cela?

Voici un exemple qui illustre la question:

df = pd.DataFrame(
    [ 
     [pd.Timestamp("2015-07-18 13:53:33.280"), 10], 
     [pd.Timestamp("2015-07-19 13:54:03.330"), 20], 
     [pd.Timestamp("2015-07-20 13:52:13.350"), 30], 
     [pd.Timestamp("2015-07-21 13:56:03.126"), 40], 
     [pd.Timestamp("2015-07-22 13:53:51.747"), 50], 
     [pd.Timestamp("2015-07-23 13:53:29.346"), 60] 
    ], 
    columns = [ 
     "datetime", 
     "value" 
    ] 
) 

df.index = df["datetime"] 
del df["datetime"] 
df.index = pd.to_datetime(df.index.values) 

df["change"] = df["value"]/df["value"].shift(freq = datetime.timedelta(days = -1)) 
+0

Où sont vos données? –

+0

@ cᴏʟᴅsᴘᴇᴇᴅ J'essaie d'éviter d'encombrer la page avec des données. J'espère que la question est assez claire et succincte. Exemple d'horodatage serait comme «2017-03-09 14: 36: 06.516166» et «2017-03-09 14: 51: 07.661818». – BlandCorporation

+1

Eh bien, sans données, les utilisateurs seront obligés de prendre des photos dans le noir :-(Une bonne approche serait d'afficher les 5-10 premières lignes des seules colonnes les plus importantes :) –

Répondre

2

j'ajouter un jour à l'index puis utilisez pd.DataFrame.reindex avec method='nearest'

df/df.set_index(df.index + pd.offsets.Day()).reindex(df.index, method='nearest') 

          value 
2015-07-18 13:53:33.280 1.000000 
2015-07-19 13:54:03.330 2.000000 
2015-07-20 13:52:13.350 1.500000 
2015-07-21 13:56:03.126 1.333333 
2015-07-22 13:53:51.747 1.250000 
2015-07-23 13:53:29.346 1.200000 

Vous pouvez fournir un autre offset une tolérance sur le method='nearest'

df/df.set_index(df.index + pd.offsets.Day()).reindex(
    df.index, method='nearest', tolerance=pd.offsets.Hour(12)) 

          value 
2015-07-18 13:53:33.280  NaN 
2015-07-19 13:54:03.330 2.000000 
2015-07-20 13:52:13.350 1.500000 
2015-07-21 13:56:03.126 1.333333 
2015-07-22 13:53:51.747 1.250000 
2015-07-23 13:53:29.346 1.200000 
+1

C'est certainement plus dans le sens de ce que OP recherche. Je suis content que vous ayez décidé de poster une réponse; Je ne me sentais pas bien avec le mien, et je peux l'enlever paisiblement maintenant. Je vous remercie! –

+0

Merci @ cᴏʟᴅsᴘᴇᴇᴅ. J'apprécie le vote de confiance. – piRSquared

+0

@BlandCorporation La seule difficulté consiste à comprendre ce que vous voulez dire. Vous pouvez corriger cette confusion en éditant votre message et en incluant ce que vous pensez que les résultats devraient être. Comme vous l'avez décrit, je pensais que ce que j'avais fourni faisait exactement cela. 60 divisé par 50 qui est venu ~ 24 heures plus tôt est de 1,2. – piRSquared

0

votre code comme suit:

df/df.shift(1) 

         value 
2015-07-18 13:53:33.280 NaN 
2015-07-19 13:54:03.330 2.000000 
2015-07-20 13:52:13.350 1.500000 
2015-07-21 13:56:03.126 1.333333 
2015-07-22 13:53:51.747 1.250000 
2015-07-23 13:53:29.346 1.200000 

Je ne peux pas sûr si elle est OK, mais il semble avoir la même réponse.