2016-04-11 3 views
2

Ich habe stündliche Daten über die Nachfrage nach Fahrradverleih und Wetter. Ich möchte die durchschnittliche Nachfrage für jede Stunde separat bei gutem und schlechtem Wetter darstellen.Gibt es eine Möglichkeit, mit einer Klausel in Python zu verwenden?

Als ich durchschnittlichen Bedarf an einer bestimmten Stunde aufgetragen (ohne Berücksichtigung Wetter photographiert), was ich tat Rechengesamtnachfrage Anmietungen an einer bestimmten Stunde war und dann durch die Gesamtzahl der Stunden unterteilt:

hour_count = np.bincount(hour) 
for i in range(number_of_observations): 
    hour_sums[hour[i]] = hour_sums[hour[i]] + rentals[i] 

av_rentals = [x/y for x,y in zip(hour_sums,hour_count)] 

Jetzt Ich würde das gleiche machen, aber getrennt für gutes Wetter und schlechtes Wetter. Die kumulative Summe war einfach, ich habe nur eine "if" -Klausel hinzugefügt. Ich weiß nicht, was ich damit machen soll, Stunden mit gutem und schlechtem Wetter zu zählen. Ich würde es vorziehen, eine große Schleife zu vermeiden, wie bei der Summe ... irgendeine Funktion, die das Gleiche tut wie eine aber mit einer Klausel? Etwas wie:

good_weather_hour_count = np.bincount(hour, weather == 1 or weather == 2) 

Irgendwelche Ideen?
PS. Vielleicht weiß jemand, wie man Mieten für eine bestimmte Stunde ohne eine Schleife zusammenfasst? Ich habe etwas mit 2D-Histogramm versucht, aber es hat nicht funktioniert.

label_sums = np.histogram2d(hour, rentals, bins=24)[0] 

Antwort

2

np.bincount has a weights parameter, die Ihnen eine BinCount der Stunden in Anspruch nehmen können durch die gewichtete Anzahl der Mieten. Zum Beispiel

In [39]: np.bincount([1,2,3,1], weights=[20,10,40,10]) 
Out[39]: array([ 0., 30., 10., 40.]) 

So können Sie die for-loop ersetzen:

for i in range(number_of_observations): 
    hour_sums[hour[i]] = hour_sums[hour[i]] + rentals[i] 

mit

hour_sums = np.bincount(hour, weights=rentals, minlength=24) 

Gut-/Schlecht-Wetter zu behandeln, könnten Sie maskieren die hour und rentals Daten, um nur die Teilmenge der Daten auszuwählen, die gilt:

mask = (weather == w) 
masked_hour = hour[mask] 
masked_rentals = rentals[mask] 

Dann machen Sie die Berechnung auf masked_hour und masked_rentals:

import numpy as np 

np.random.seed(2016) 
N = 2 
hour = np.tile(np.arange(24), N) 
rentals = np.random.randint(10, size=(len(hour),)) 
# say, weather=1 means good weather, 2 means bad weather 
weather = np.random.randint(1, 3, size=(len(hour),)) 

average_rentals = dict() 
for kind, w in zip(['good', 'bad', 'all'], [1, 2, None]): 
    if w is None: 
     mask = slice(None) 
    else: 
     mask = (weather == w) 
    masked_hour = hour[mask] 
    masked_rentals = rentals[mask] 
    total_rentals = np.bincount(masked_hour, weights=masked_rentals, minlength=24) 
    total_hours = np.bincount(masked_hour, minlength=24) 
    average_rentals[kind] = (total_rentals/total_hours) 

for kind, result in average_rentals.items(): 
    print('\n{}: {}'.format(kind, result)) 

ergibt

bad: [ 4. 6. 2. 5.5 nan 4. 4. 8. nan 3. nan 2.5 4. nan 9. 
    nan 3. 5.5 8. nan 8. 5. 9. 4. ] 

good: [ 3. nan 4. nan 8. 4. nan 7. 5.5 2. 4. nan nan 0.5 9. 
    0.5 nan nan 5. 7. 1. 7. 8. 0. ] 

all: [ 3.5 6. 3. 5.5 8. 4. 4. 7.5 5.5 2.5 4. 2.5 4. 0.5 9. 
    0.5 3. 5.5 6.5 7. 4.5 6. 8.5 2. ] 
1

Ich bin über Numpy nicht sicher, aber man konnte dies ziemlich leicht mit der Standardbibliothek tun:

from collections import Counter, defaultdict 

weather_counts = defaultdict(Counter) 

times = [ 
    {'time': '1:00 AM', 'weather': 1}, 
    {'time': '2:00 AM', 'weather': 2}, 
    {'time': '5:00 PM', 'weather': 2}, 
    {'time': '3:00 AM', 'weather': 1}, 
    {'time': '1:00 AM', 'weather': 1}, 
] 

rentals = [ 
    1, 
    2, 
    5, 
    3, 
    3, 
] 

for times, rental_count in zip(times, rentals): 
    weather_counts[times['weather']][times['time']] += rental_count 

import pprint; pprint.pprint(weather_counts) 
Verwandte Themen