2 votes

Python - NumPy.Where avec un dictionnaire

Il se peut que je me trompe, ou qu'il y ait une meilleure façon de procéder, car je suis encore novice en Python. Je m'excuse d'avance pour toute erreur évidente.

J'ai un Dataframe Pandas avec une colonne STR qui contient une date et une heure. Elle est STR parce que les heures sont formatées "Broadcast", ce qui signifie qu'il y a 29 heures dans la journée. Nous verrons donc des dates comme 01/Jan/2018 29:59:59. En ajoutant une seconde à cette date, on obtient 02/Jan/2018 06:00:00.

Mon objectif est de convertir ces données en temps réel. Ce qui signifie que toute heure comprise entre 24 et 29 nécessite également un décalage de date. J'ai déjà divisé le STR en 2 nouvelles colonnes ['Dt'] et ['Ti'], à partir de ['Ti'], j'ai extrait l'heure dans une nouvelle colonne ['Hr'] et j'en ai fait un INT.

J'ai ensuite appliqué un pd.to_datetime au ['Dt'] et ajouté une règle.

df['Dt'] = np.where(df['Hr'] > 23, df['Dt']+pd.DateOffset(1),df['Dt']+pd.DateOffset(0) )

cela fonctionne parfaitement.

Je dois maintenant modifier l'heure pour qu'elle soit en temps réel, par exemple, 24 = 00, 25 = 02, etc.

J'ai pensé que la meilleure façon était d'utiliser un DICT et de le cartographier, j'ai donc créé un DICT,

HourMap = {'24':'00','25':'01','26':'02','27':'03','28':'04','29':'05','30':'06'}  

Puis il a écrit ceci

df['Hr1'] = np.where(df['Hr'] > 23, df.replace({'Hr':HourMap}),df['Hr'])

Mais j'obtiens une "ValueError" (erreur de valeur)

ValueError: operands could not be broadcast together with shapes (273,) (273,29) (273,)

J'ai examiné ces lignes dans le cadre de données et ce ne sont que des INT normaux. En testant, je peux leur appliquer des mathématiques (par exemple, df['Test'] = df['Hr'] + 1.

Je les ai convertis en STR et j'ai essayé les mêmes règles, mais j'ai obtenu la même erreur.

Suis-je fou ?

Merci,

3voto

jezrael Points 290608

Je crois qu'il faut changer :

df.replace({'Hr':HourMap})

à map et si certaines valeurs ne correspondent pas et sont renvoyées NaN le remplace par les valeurs d'origine par fillna :

df['Hr'].map(HourMap).fillna(df['Hr'])
#alternative solution if performance is not important in large df
#df['Hr'].replace(HourMap)

parce que df.replace renvoie toutes les colonnes du DataFrame avec la colonne remplacée Hr

2voto

Dan Points 18107

Vous ne devriez vraiment pas utiliser un dictionnaire ici, vous n'avez même pas besoin de l'option np.where . Utiliser le opérateur modulo

In [1]: import numpy as np
In [2]: np.arange(31)%24
Out[2]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23,  0,  1,  2,  3,  4,  5, 6], dtype=int32)

Vous avez des nombres qui "s'enroulent" autour de 24, c'est le cas d'utilisation classique du modulo. Le code complet devient donc :

df['Hr1'] = df['Hr'] % 24

De la même manière, vous pouvez ajouter des dates à votre agenda sans np.where en utilisant simplement la division en nombres entiers

df['Dt'] = df['Dt']+pd.DateOffset(Df['Hr']//24)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X