J'ai la trame de données Pandas suivante, où l'heure (durée) est donnée dans un format très étrange:

Person   Activity   Duration
1        A          1 00:00
2        A          1 00:00
3        B          0 21:17
4        C          0 17:11

1 00:00 signifie 24 heures et 0 21:17 signifie 0 jour et 21:17 heures, c'est-à-dire seulement 21:17 heures. Un rapide coup d'œil aux dtypes renvoie:

In[1]: df.dtypes
Out[1]: 
Person         object
Activity       object
Duration       object
dtype: object

Comment puis-je traiter systématiquement la colonne Duration pour renvoyer 24 si la valeur est 1 00:00 et la valeur décimale de la durée si j'ai 0 21:17? La valeur décimale de 0 21:17 serait 21,283.

Le résultat devrait être:

Person   Activity   Duration
1        A          24
2        A          24
3        B          21.283
4        C          17.183
1
Zizzipupp 2 juin 2020 à 18:32

5 réponses

Meilleure réponse

Comme vous l'avez mentionné, cela ne dépassera pas 13h00, c'est-à-dire minuit, il existe un moyen plus simple:

'''
Person  Activity    Duration
1   A   1 00:00
2   A   1 00:00
3   B   0 21:17
4   C   0 17:11
'''

import pandas as pd

df = pd.read_clipboard("\t")

.

   Person Activity Duration
0       1        A  1 00:00
1       2        A  1 00:00
2       3        B  0 21:17
3       4        C  0 17:11   

.

df['Duration'] = df['Duration'].str.split(' ')

df['Duration'] = ['24:00' if int(val[0]) == 1 else val[1] for val in df['Duration']]

print(df)

.

   Person Activity Duration
0       1        A    24:00
1       2        A    24:00
2       3        B    21:17
3       4        C    17:11
2
Anshul 2 juin 2020 à 15:51
a = np.array([24, 1, 1/60])    
df.Duration = df.Duration.str.split(' |:', expand=True).astype(int).dot(a)

Exemple:

df = pd.DataFrame({'Person': [1,2,3,4], "Activity": list('AABC') ,"Duration":['1 00:00', '1 00:00', '0 21:17', '0 17:11']})
df.Duration = df.Duration.str.split(' |:', expand=True).astype(int).dot(a)
print(df)
#   Person Activity   Duration
#0       1        A  24.000000
#1       2        A  24.000000
#2       3        B  21.283333
#3       4        C  17.183333
4
Stef 2 juin 2020 à 15:51

Vous pouvez simplement multiplier et additionner ces nombres facilement:

durations = [   
    "1 00:00",
    "0 21:17",          
]                                                                        

for duration in durations: 
    day, clock = duration.split()
    hour, minute = clock.split(':')
    print((int(day) * 24) + int(hour) + (int(minute) / 60))
2
match 2 juin 2020 à 15:42

En plus des autres réponses utiles, je voulais publier ma propre solution, qui utilise une fonction personnalisée et l'applique à un dataframe en utilisant df.apply:

def custom_time_to_decimals(value):
    if value.split()[0]=='1':
        return 24
    else:
        custom = value.split()[1]
        hours = int(custom[0:2])
        minutes = int(custom[3:5])
        decimal = hours + (minutes/60)
        return round(decimal,3)

df['decimalHours'] = df['<insertYourTimeColumnHere>'].apply(custom_time_to_decimals)
1
Zizzipupp 2 juin 2020 à 15:53

Vous pouvez utiliser le module datetime pour la conversion de l'heure

from datetime import datetime
def durationInDecimal(string):
    day, time = string.split(" ")
    t = datetime.strptime(time, "%H:%M").time()
    return int(day)*24 + (t.hour+t.minute/60.0)


df = pd.DataFrame({'Person': list("ABCD"), "Activity": list('ABCD') ,"duration":['1 00:00', '1 00:00', '0 21:17', '0 17:11']})
df["duration"] = df.duration.apply(durationInDecimal)

# Person    Activity    duration
# 0 A   A   24.000000
# 1 B   B   24.000000
# 2 C   C   21.283333
# 3 D   D   17.183333
1
Anurag Wagh 2 juin 2020 à 16:03