2016-05-06 2 views
0

J'ai lu le tableau des transactions de ventes d'Excel, et je suis intéressé de connaître le nombre de ventes dans l'heure qui suit la première vente des articles. Soit A être le rapport des ventes, je veux créer B.Comment obtenir les lignes dans un délai en utilisant Python?

A= 
item Location time 
X  Canada  10:03:18 
X  Canada  10:08:38 
X  Canada  10:24:46 
X  Canada  11:16:35 
X  US   10:00:16 
X  US   11:52:12 
Y  Canada  2:08:38 
Y  Canada  4:01:48 
Y  US   13:32:02 
Y  US   14:07:03 

B= 
item location first sale count 
X  Canada  10:03:18 3 
X  US   10:00:16 1 
Y  Canada  2:08:38  1 
Y  US   13:32:02 2 

Voici ce que je faisais:

A= A.sort('time', ascending=True).reset_index() 
sale_loc= pd.DataFrame(A.groupby(['item', 'Location'], sort = False).first()).reset_index() 
for i in sale_loc.index: 
    sale_cutoff = (A.time[i] + dt.timedelta(hours=1)).time 

Mais j'obtiens l'erreur pour la partie de la manipulation du temps. J'ai essayé différentes fonctions, et j'ai aussi essayé d'ajouter une nouvelle colonne A (heure + 1 heure) au lieu de la boucle, mais problème similaire ...

Répondre

0
import numpy as np 
import pandas as pd 

df = pd.DataFrame({'Location': ['Canada', 'Canada', 'Canada', 'Canada', 'US', 'US', 'Canada', 'Canada', 'US', 'US'], 'item': ['X', 'X', 'X', 'X', 'X', 'X', 'Y', 'Y', 'Y', 'Y'], 'time': ['10:03:18', '10:08:38', '10:24:46', '11:16:35', '10:00:16', '11:52:12', '2:08:38', '4:01:48', '13:32:02', '14:07:03']}) 

df['start'] = pd.to_datetime(df['time']) 
grouped = df.groupby(['item', 'Location']) 
df['end'] = (grouped['start'].transform(lambda grp: grp.min()+pd.Timedelta(hours=1))) 
df['mask'] = (df['start'] < df['end']) 

result = grouped['mask'].sum() 
print(result) 

rendements

item Location 
X  Canada  3.0 
     US   1.0 
Y  Canada  1.0 
     US   2.0 
Name: mask, dtype: float64 

La principale idée est de regrouper par item et Location, trouver le temps minimum de départ pour chaque groupe, puis ajoutez 1 heure:

df['end'] = (grouped['start'].transform(lambda grp: grp.min()+pd.Timedelta(hours=1))) 

transform retourne une série de la même longueur que df, de sorte que chaque rangée obtient une valeur:

In [319]: df 
Out[319]: 
    Location item  time    start     end 
0 Canada X 10:03:18 2016-05-06 10:03:18 2016-05-06 11:03:18 
1 Canada X 10:08:38 2016-05-06 10:08:38 2016-05-06 11:03:18 
2 Canada X 10:24:46 2016-05-06 10:24:46 2016-05-06 11:03:18 
3 Canada X 11:16:35 2016-05-06 11:16:35 2016-05-06 11:03:18 
4  US X 10:00:16 2016-05-06 10:00:16 2016-05-06 11:00:16 
5  US X 11:52:12 2016-05-06 11:52:12 2016-05-06 11:00:16 
6 Canada Y 2:08:38 2016-05-06 02:08:38 2016-05-06 03:08:38 
7 Canada Y 4:01:48 2016-05-06 04:01:48 2016-05-06 03:08:38 
8  US Y 13:32:02 2016-05-06 13:32:02 2016-05-06 14:32:02 
9  US Y 14:07:03 2016-05-06 14:07:03 2016-05-06 14:32:02 

Maintenant, vous pouvez facilement identifier les lignes d'intérêt. Ils sont ceux où start est inférieur à end:

In [320]: df['mask'] = (df['start'] < df['end']) 
In [321]: df 
Out[321]: 
    Location item  time    start     end mask 
0 Canada X 10:03:18 2016-05-06 10:03:18 2016-05-06 11:03:18 True 
1 Canada X 10:08:38 2016-05-06 10:08:38 2016-05-06 11:03:18 True 
2 Canada X 10:24:46 2016-05-06 10:24:46 2016-05-06 11:03:18 True 
3 Canada X 11:16:35 2016-05-06 11:16:35 2016-05-06 11:03:18 False 
4  US X 10:00:16 2016-05-06 10:00:16 2016-05-06 11:00:16 True 
5  US X 11:52:12 2016-05-06 11:52:12 2016-05-06 11:00:16 False 
6 Canada Y 2:08:38 2016-05-06 02:08:38 2016-05-06 03:08:38 True 
7 Canada Y 4:01:48 2016-05-06 04:01:48 2016-05-06 03:08:38 False 
8  US Y 13:32:02 2016-05-06 13:32:02 2016-05-06 14:32:02 True 
9  US Y 14:07:03 2016-05-06 14:07:03 2016-05-06 14:32:02 True 

Regroupement une fois par item et Location, le résultat souhaité est obtenu en additionnant le nombre de fois mask est vrai pour chaque groupe:

result = grouped['mask'].sum() 
+0

Merci pour la réponse complète, je pense que «transformer» était ce qui me manquait lorsque j'ai essayé cette approche en premier. Ça marche bien! – Ana

1

Plutôt que de produire l'ensemble du code, je me suis concentré sur la section que vous avez indiquée qui lançait des erreurs. Ceci est un exemple pratique d'ajout d'une heure aux heures que vous listez:

sale_time = ['10:03:18', '10:08:38', '11:16:35', '10:00:16'] 

import datetime 
for i in sale_time: 
    sale_time1 = datetime.time(hour = int(i[0:2]), minute=int(i[3:5]), second=int(i[6:8])) 
    print(sale_time1) 
    sale_cutoff = datetime.time(sale_time1.hour+1, sale_time1.minute, sale_time1.second) 
    print(sale_cutoff) 
+0

Merci @mjp, il corrige le problème de manipulation du temps avec l'approche en boucle. – Ana

+0

Hey @Ana, heureux que cela a aidé. P.s. votre édition était complètement correcte - il y avait une incohérence de nommage là. Aucune idée pourquoi les gens l'ont rejeté. J'ai modifié le poste pour la cohérence – mjp