lire les données
import pandas df = pandas.read_table(file, header = False, sep = "\t", decimal = ",", parse_dates = ["last_update"], date_parser = lambda s : datetime.datetime.strptime (s, "%d/%m/%Y %H:%M"))
la première et la dernière dates
print ("min_date", df["last_update"].min()) print ("max_date", df["last_update"].max())
le nombre maximum de vélos et de places vides
print ("max velo", df["available_bikes"].max()) print ("max_place", df["available_bike_stands"].max())
la proportion du temps durant lequel la station n'a pas de vélos disponibles
print ("pas de vélo", len(df [ df["available_bikes"]==0 ]) / len(df) )
la proportion du temps durant lequel la station n'a pas de places disponibles
print ("pas de place", len(df [ df["available_bike_stands"]==0 ]) / len(df) )
le nombre d'emplacements de vélos à cette station
add = df["available_bikes"] + df["available_bike_stands"] print (add.max())
visualisation des données avec pandas
import matplotlib.pyplot as plt df = df.set_index("last_update") ts = df.ix[:,"available_bikes"] ts.plot() plt.show()
seconde visualisation avec matplotlib
import numpy from matplotlib.mlab import csv2rec import matplotlib.pyplot as plt import matplotlib.cbook as cbook from matplotlib.ticker import Formatter class MyFormatter(Formatter): def __init__(self, dates, fmt='%Y-%m-%d'): self.dates = dates self.fmt = fmt def __call__(self, x, pos=0): 'Return the label for time x at position pos' ind = int(round(x)) if ind>=len(self.dates) or ind<0: return '' return self.dates[ind].strftime(self.fmt) formatter = MyFormatter(df["last_update"]) fig, ax = plt.subplots() ax.xaxis.set_major_formatter(formatter) ax.plot(numpy.arange(len(ts)), ts, '-') fig.autofmt_xdate() plt.show()
ajouter une colonne contenant le jour de la semaine et l'heure
df2["weekday"] = df2['last_update'].map(lambda d: str(d.weekday()) + "-" + d.strftime("%H:%M"))
aligner les données par jour de la semaine
df2["weekno"] = df2['last_update'].map(lambda d: d.isocalendar()[1]) sp = "available_bikes weekday weekno".split() sem = df2.ix[:,sp] piv = sem.pivot ('weekday', "weekno", "available_bikes") piv.plot() # pour visualiser les données plt.show()
exercice 1 : lissage
# on somme la série complète 12 fois mais décalé à chaque fois nbperiod = 12 mat = numpy.matrix ( [0.0] * (len( df2 ) - nbperiod+1) ).transpose() for i in range(0,nbperiod) : r = df2.ix[i:len(df2)-nbperiod+i,'available_bikes'] m = numpy.matrix(list(r)).transpose() mat += m mat /= 1.0 * nbperiod # on élimine les premières et dernières valeurs df2 = df2[nbperiod/2:-nbperiod/2+1] df2["lisse"] = mat # on répète la même manipulation pour superposer les semaines sp = "lisse weekday weekno".split() sem = df2.ix[:,sp] piv = sem.pivot ('weekday', "weekno", "lisse") piv.plot() plt.show()
exercice 1 : lissage avec les fonctions évoluées de pandas
df2 = df.ix[:, ["last_update","available_bikes"]] # on ajoute une colonne lissage qui contient la moyenne mobile sur 12 périodes via la fonction rolling_mean df2["lissage"] = pandas.stats.moments.rolling_mean(df2["available_bikes"],12) # on fait la meme transformation que dans l'exercice précédent pour afficher la valeur lissée par semaine, par timebox df2["weekday"] = df2['last_update'].map(lambda d: str(d.weekday()) + "-" + d.strftime("%H:%M")) df2["weekno"] = df2['last_update'].map(lambda d: d.isocalendar()[1]) serietemp = df2.ix[:,["lissage","weekday","weekno"]] piv = serietemp.pivot ("weekday", "weekno", "lissage") piv.plot() # pour visualiser les données plt.show()
exercice 2 : données manquantes
beg = "4-16:00" piv = thispiv piv.ix[beg:,31] = numpy.NaN mx = numpy.array(piv.as_matrix()) for i,k in enumerate(piv.index) : if k >= beg and numpy.isnan(piv.ix[k,31]): ave_week = numpy.average( mx[~numpy.isnan(mx[:,2]),2]) ave_hour = numpy.average( mx[i, ~numpy.isnan(mx[i,:])] ) piv.ix[k,31] = (ave_week*ave_hour)**0.5 piv.plot() plt.show()