J'ai un DataFrame df avec 200 lignes. Les premières lignes ressemblent à ceci:
+--------------+----------+----------------+ |Customer name | Arrival | Actual Arrival | +--------------+----------+----------------+ | Customer 21 | 20 | 07:20 | | Customer 22 | 30 | 07:30 | | Customer 23 | 20 | 07:20 | | Customer 24 | 10 | 07:10 | | Customer 25 | 60 | 08:00 | +--------------+----------+----------------+
La colonne Arrivée indique l'heure d'arrivée en minutes à partir de l'heure de début. Je souhaite donc créer la colonne Arrivée réelle en ajoutant un horodatage fixe (heure de début) aux valeurs de la colonne Arrivée. Exemple: si l'heure de début est 07:00;
+--------------+----------+----------------+ |Customer name | Arrival | Actual Arrival | +--------------+----------+----------------+ | Customer 21 | 20 | | | Customer 22 | 30 | | | Customer 23 | 20 | | | Customer 24 | 10 | | | Customer 25 | 20 | | +--------------+----------+----------------+
Comment faire cela en python ??
3 Réponses :
Pouvez-vous essayer ce qui suit:
>>> df['Actual Arrival'] = df['Arrival'].apply(lambda x: (start_time + datetime.timedelta(minutes=x)).time()) >>> df name Arrival Actual Arrival 0 1 5 07:05:00 1 2 6 07:06:00 2 3 7 07:07:00 3 4 8 07:08:00
Exemple:
>>> df = pd.DataFrame([[1, 2, 3, 4], [5, 6, 7, 8]]).T
>>> df.columns = ['name', 'Arrival']
>>> df
name Arrival
0 1 5
1 2 6
2 3 7
3 4 8
>>> start_time = datetime.datetime.strptime('2019-05-17 7:0:0', '%Y-%m-%d %H:%M:%S')
>>> df['Actual Arrival'] = df['Arrival'].apply(lambda x: start_time + datetime.timedelta(minutes=x))
>>> df
name Arrival Actual Arrival
0 1 5 2019-05-17 07:05:00
1 2 6 2019-05-17 07:06:00
2 3 7 2019-05-17 07:07:00
3 4 8 2019-05-17 07:08:00
Si vous ne voulez que l'heure, vous pouvez faire ce qui suit:
import datetime actual_start_time = datetime.time(7, 0) start_time = datetime.datetime.combine(datetime.datetime.today().date(), actual_start_time) df['Actual Arrival'] = df['Arrival'].apply(lambda x: start_time + datetime.timedelta(minutes=x))
Faites-moi savoir si vous avez des problèmes
Merci Jeril. Cela marche. Est-il possible de définir l'heure de début comme heure (et non comme date / heure) afin de ne pas avoir à supprimer l'heure dans la fonction lambda?
Je suppose que le delta temporel fonctionne avec datetime.datetime et non avec datetime.time , vous devez combiner datetime.time avec datetime. datetime.today () . Faites-moi savoir si vous voulez ça
Essayez ceci si vous ne voulez utiliser que time () pour l'heure de base:
base_time = (7, 0, 0) # (hour, minute, seconds) base = datetime.time(*base_time) # If you want to have it as a time object in your code. It is redundant now. actual_arrival = datetime.time(*add_times(base_time, (0, 20, 0)))
Ceci renvoie:
def add_times(op1, op2): # two tuples in this format: (h, m, s)
hour = op1[0] + op2[0]
minute = op1[1] + op2[1]
second = op1[2] + op2[2]
if second >= 60:
minute += 1
second -= 60
if minute >= 60:
hour += 1
minute -= 60
if hour >= 24:
hour -= 24
return (hour, minute, second)
MODIFIER: Notez que dans l'approche ci-dessus, les arguments de time () doivent être valides et si votre minute devient supérieure à 59, elle gagne » t travailler.
Pour contourner ce problème, vous pouvez définir une fonction d'assistance pour ce faire:
07:20:00
et changer le code en:
import datetime arrival = 20 base = datetime.time(7, 0, 0) # 07:00:00 or whatever your base time is. actual_arrival = datetime.time(base.hour, base.minute + arrival, base.second)
Mais je pense que ce n'est plus une approche datetime pour résoudre votre problème.
cela ne fonctionnera pas lorsque l ' arrivée est supérieure à 59, vous obtiendrez l'erreur suivante ValueError: minute must be in 0..59
import datetime
data = {'customers': {0: 'Customer 21',
1: 'Customer 22',
2: 'Customer 23',
3: 'Customer 24',
4: 'Customer 25'},
'arrival': {0: 20, 1: 30, 2: 20, 3: 10, 4: 60}}
df = pd.DataFrame(data)
df['actual arrival'] = df.arrival.apply(lambda x:(pd.to_datetime(datetime.datetime.today().date())+pd.offsets.Timedelta(hours=7,minutes=x)).strftime('%H:%M'))