2016-05-06 26 views
0

Ich lese die Umsatztransaktionstabelle aus Excel, und ich bin interessiert, die Anzahl der Verkäufe innerhalb von 1 Stunde nach den ersten verkauften Artikeln zu erfahren. Lassen Sie A der Verkaufsbericht sein, ich möchte B erstellen.Wie erhalten Sie die Zeilen innerhalb eines Zeitlimits mit 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 

Das ist, was ich tat:

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 

Aber ich bekomme Fehler für die Manipulation in Teilzeit. Ich habe versucht, verschiedene Funktionen, und ich habe auch versucht, eine neue Spalte A (Zeit + 1 Stunde) statt der Schleife hinzufügen, aber ähnliches Problem ...

Antwort

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) 

Ausbeuten

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

der Haupt Idee ist, zu einer Gruppe von item und Location finden das Minimum für jede Gruppe Startzeit, und fügen Sie dann 1 Stunde:

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

transform gibt eine Serie von gleicher Länge wie df, so dass jede Zeile erhält einen Wert:

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 

Jetzt können Sie ganz einfach die Reihen von Interesse identifizieren. Sie sind diejenigen, in denen start weniger als 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 

Gruppierung erneut von item und Location, das gewünschte Ergebnis durch Addition die Anzahl der gefunden wird mask für jede Gruppe Wahr ist:

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

Danke für die vollständige Antwort, ich denke, "Transform" war, was ich fehlte, wenn ich diesen Ansatz zuerst versuchte. Es läuft gut! – Ana

1

Anstatt den gesamten Code zu erstellen, habe ich mich auf den Abschnitt konzentriert, den Sie angegeben haben, Fehler zu werfen. Dies ist ein funktionierendes Beispiel zum Hinzufügen einer Stunde zu den Zeiten, die Sie auflisten:

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

Danke @mjp, es behebt das Zeitmanipulationsproblem mit dem Loop-Ansatz. – Ana

+0

Hey @Ana, froh, dass es geholfen hat. Ps.s. Ihre Bearbeitung war völlig korrekt - da gab es eine Benennungsinkonsistenz. Keine Ahnung, warum die Leute es abgelehnt haben. Ich habe den Beitrag aus Konsistenzgründen bearbeitet – mjp