ANALÝZA STANIC SDÍLENÝCH KOL

V

EDINBURGHU

Použité technologie: Pandas, Python, SQL, Jupyter.

  • Identifikujte aktivní a neaktivní stanice,
  • identifikujte nejfrekventovanější stanice,
  • identifikujte stanice, na kterých se kola hromadí a stanice, kde potenciálně chybí,
  • spočítejte vzdálenosti mezi jednotlivými stanicemi,
  • jak dlouho trvá jedna výpůjčka? Najděte odlehlé hodnoty, zobrazte histogram.
  • Proveťe analýzu poptávky:

    • zobrazte vývoj poptávky po půjčování kol v čase,
    • identifikujte příčiny výkyvů poptávky,
    • zjistěte vliv počasí na poptávku po kolech (údaje o počasí v Edinburghu jsou v tabulce edinburgh_weather),
    • půjčují si lidé kola více o víkendu než během pracovního týdne?
  •  

VÝSTUPY

ANALÝZY

 

  • Vidíme jednoznačný vliv sezóny na poptávku,
  • vliv eventů ve městě,
  • vliv Covidových lockdownů ve Skotsku – první ohlášen 20.3.2020 a postupné uvolňování pravidel od 11.5.2020 až do návratu dětí do škol 11.8.2020.

Během jara a léta byl vliv počasí na výpůjčky kol v Edinburghu spíše méně významný. Během sledovaného období bylo počasí bez vichřic, extrémních teplot, nebo mimořádně vydatných srážek. Zdá se, že větší vliv na výpůjčky mělo pořádání eventů ve městě. 

Efekt teploty vzduchu na poptávku je střední: R = 0,5.

Během hlavní sezóny se vliv teploty vzduchu ztrácí: R = 0,36.

Po odstranění vlivu eventů ve městě je vliv počasí na výpůjčky ještě menší: R = 0,31.

Lidé si kola půjčují o víkendu trochu

více, než během pracovního týdne.

Průměrný denní počet výpůjček během pracovních dnů: 

 387

 Průměrný denní počet výpůjček během víkendu: 

 443

Doba výpůjčky mezi 5 a 20 minutami jednoznačně dominuje počtem kolem 180 tis. záznamů z celkových 438 259 výpůjček.

Asi 80% lidí vrátí kolo do 60 minut.

 

Deset nejfrekventovanějších stanic (výpůjčky + vratky)

Jedna z možností tabulky vzdáleností mezi stanicemi.

POSTUP

Načtení dat do Jupyter notebook.

Výstupem je tabulka s daty o výpůjčkách kol. Vidíme identifikace stanic výpůjček a vrácení včetně jejich názvů, popisu, souřadnic a doby výpůjčky v sekundách.

IN:

alchemy_conn = sqlalchemy.create_engine(conn_string)
edbikes_df = pd.read_sql(‚edinburgh_bikes‘,conn_string,index_col=[‚index‘])
edbikes_df.head()

OUT:

index started ended durationstart station id start station name start station description start station latitude start station longitude end station id end station name  end station descriptionend station latitude end station longitude 
02018-09-15 08:52:052018-09-15 09:11:481182247Charlotte SquareNorth Corner of Charlotte Square55.952335-3.207101259St Andrew SquareNorth East corner55.954728-3.192653
12018-09-15 09:24:332018-09-15 09:41:09995259St Andrew SquareNorth East corner55.954749-3.192774262Canonmillsnear Tesco’s55.962804-3.196284
22018-09-15 09:48:542018-09-15 10:46:403466262Canonmillsnear Tesco’s55.962804-3.196284250Victoria QuayEntrance to Scottish Government Office55.977638-3.174116
32018-09-16 12:01:362018-09-16 12:25:261430255Kings Buildings 4X-Y Cafe55.922001-3.176902254Kings Building 3Kings Building House55.923479-3.175385
42018-09-16 12:03:432018-09-16 12:11:16452255Kings Buildings 4X-Y Cafe55.922001-3.176902253Kings Building 2Sanderson Building55.923202-3.171646

Informace o datech.

Tabulká má 438 259 záznamů. Některé sloupce mají nižší počty záznamů, takže v nich data chybí.

IN:

edbikes_df.info()

OUT:

<class 'pandas.core.frame.DataFrame'>
Int64Index: 438259 entries, 0 to 12640
Data columns (total 13 columns):
 #   Column                     Non-Null Count   Dtype  
---  ------                     --------------   -----  
 0   started_at                 438259 non-null  object 
 1   ended_at                   438259 non-null  object 
 2   duration                   438259 non-null  int64  
 3   start_station_id           438259 non-null  int64  
 4   start_station_name         438259 non-null  object 
 5   start_station_description  435549 non-null  object 
 6   start_station_latitude     438259 non-null  float64
 7   start_station_longitude    438259 non-null  float64
 8   end_station_id             438259 non-null  int64  
 9   end_station_name           438259 non-null  object 
 10  end_station_description    435256 non-null  object 
 11  end_station_latitude       438259 non-null  float64
 12  end_station_longitude      438259 non-null  float64
dtypes: float64(4), int64(3), object(6)
memory usage: 46.8+ MB

Záznamy jsou z období od 15.9.2018 do 30.6.2021.

IN:

edbikes_df[[‚started_at‘,’ended_at‘]].sort_values(‚started_at‘)

OUT:

  
index started_atended_at 
02018-09-15 08:52:052018-09-15 09:11:48
12018-09-15 09:24:332018-09-15 09:41:09
22018-09-15 09:48:542018-09-15 10:46:40
32018-09-16 12:01:362018-09-16 12:25:26
42018-09-16 12:03:432018-09-16 12:11:16
126362021-06-30 23:30:312021-07-01 00:06:10
126372021-06-30 23:36:162021-07-01 00:05:40
126382021-06-30 23:49:032021-07-01 00:11:25
126392021-06-30 23:49:032021-07-01 00:11:52
126402021-06-30 23:58:332021-07-01 00:07:15

438259 rows × 2 columns

Hledání chybějících hodnot.

Ve sloupci start_station_description chybí 2710 hodnot a ve sloupci end_station_description jich chybí 3003.

IN:

edbikes_df.isna().sum()

OUT:

started_at                      0
ended_at                        0
duration                        0
start_station_id                0
start_station_name              0
start_station_description    2710
start_station_latitude          0
start_station_longitude         0
end_station_id                  0
end_station_name                0
end_station_description      3003
end_station_latitude            0
end_station_longitude           0
dtype: int64

Identifikace řádků s chybějícími hodnotami v start_station_description.

Hodnoty chybí v počátečních stanicích s názvem ‚Dalry Road Lidl‘.

IN:

condition = edbikes_df[[‚start_station_name‘,’start_station_description‘]].isna().any(axis=1)
edbikes_df.loc[condition,’start_station_name‘].unique()

OUT:

array(['Dalry Road Lidl'], dtype=object)

Identifikace řádků s chybějícími hodnotami v end_station_description.

Hodnoty chybí v konečných stanicích s názvem ‚Dalry Road Lidl‘.

IN:

condition = edbikes_df[[‚end_station_name‘,’end_station_description‘]].isna().any(axis=1)
edbikes_df.loc[condition,’end_station_name‘].unique()

OUT:

array(['Dalry Road Lidl'], dtype=object)

Doplnění chybějících hodnot do tabulky.

IN:

edbikes_df.fillna(‚Dalry Road Lidl‘,inplace=True)

edbikes_df.info()

OUT:

<class 'pandas.core.frame.DataFrame'>
Int64Index: 438259 entries, 0 to 12640
Data columns (total 13 columns):
 #   Column                     Non-Null Count   Dtype  
---  ------                     --------------   -----  
 0   started_at                 438259 non-null  object 
 1   ended_at                   438259 non-null  object 
 2   duration                   438259 non-null  int64  
 3   start_station_id           438259 non-null  int64  
 4   start_station_name         438259 non-null  object 
 5   start_station_description  438259 non-null  object 
 6   start_station_latitude     438259 non-null  float64
 7   start_station_longitude    438259 non-null  float64
 8   end_station_id             438259 non-null  int64  
 9   end_station_name           438259 non-null  object 
 10  end_station_description    438259 non-null  object 
 11  end_station_latitude       438259 non-null  float64
 12  end_station_longitude      438259 non-null  float64
dtypes: float64(4), int64(3), object(6)

Výpis počátečních stanic: ID, jméno, popis, souřadnice.

drop_duplicates() vyřadí duplicity (srovnává řádky tabulky jako celek).

IN:

start = (edbikes_df[[‚start_station_id‘,’start_station_name‘,’start_station_latitude‘,’start_station_longitude‘, ‚start_station_description‘]].drop_duplicates()
.rename(columns={‚start_station_id‘:’station_id‘,’start_station_name‘:’station_name‘,’start_station_latitude‘:’latitude‘,
‚start_station_longitude‘:’longitude‘,’start_station_description‘:’station_description‘})
)
print(‚Start stations:‘)
print(‚\n‘,start)

OUT:

Start stations:

        station_id               station_name   latitude  longitude  \
index                                                                
0             247           Charlotte Square  55.952335  -3.207101   
1             259           St Andrew Square  55.954749  -3.192774   
2             262                 Canonmills  55.962804  -3.196284   
3             255          Kings Buildings 4  55.922001  -3.176902   
5             253           Kings Building 2  55.923202  -3.171646   
...           ...                        ...        ...        ...   
5853         2268               Picady Place  55.956535  -3.186248   
5970         2268              Picardy Place  55.956535  -3.186248   
3490         2265   Musselburgh Brunton Hall  55.943961  -3.058307   
33            358                 Leith Walk  55.965176  -3.176180   
9257         1739  Edinburgh Royal Infirmary  55.921354  -3.136971   

                      station_description  
index                                      
0        North Corner of Charlotte Square  
1                       North East corner  
2                            near Tesco's  
3                                X-Y Cafe  
5                      Sanderson Building  
...                                   ...  
5853                  Outside Omni Centre  
5970                  Outside Omni Centre  
3490     Adjacent to the Brunton Theatre   
33     Leith Walk opposite Dalmeny Street  
9257      Front of new Sick Kids Hospital  

[241 rows x 5 columns]

Výpis konečných stanic: ID, jméno, popis, souřadnice.

drop_duplicates() vyřadí duplicity (pouze pokud se hodnoty shodují ve všech vypsaných sloupcích).

IN:

end = (edbikes_df[[‚end_station_id‘,’end_station_name‘,’end_station_latitude‘,’end_station_longitude‘,’end_station_description‘]].drop_duplicates()
.rename(columns={‚end_station_id‘:’station_id‘,’end_station_name‘:’station_name‘,’end_station_latitude‘:’latitude‘,
‚end_station_longitude‘:’longitude‘,’end_station_description‘:’station_description‘})
)
print(„End stations:“)
print(‚\n‘,end)

OUT:

End stations:

        station_id               station_name   latitude  longitude  \
index                                                                
0             259           St Andrew Square  55.954728  -3.192653   
1             262                 Canonmills  55.962804  -3.196284   
2             250              Victoria Quay  55.977638  -3.174116   
3             254           Kings Building 3  55.923479  -3.175385   
4             253           Kings Building 2  55.923202  -3.171646   
...           ...                        ...        ...        ...   
5806         2268               Picady Place  55.956535  -3.186248   
5963         2268              Picardy Place  55.956535  -3.186248   
3184         2265   Musselburgh Brunton Hall  55.943961  -3.058307   
12970         358                 Leith Walk  55.965176  -3.176180   
9272         1739  Edinburgh Royal Infirmary  55.921354  -3.136971   

                          station_description  
index                                          
0                           North East corner  
1                                near Tesco's  
2      Entrance to Scottish Government Office  
3                        Kings Building House  
4                          Sanderson Building  
...                                       ...  
5806                      Outside Omni Centre  
5963                      Outside Omni Centre  
3184         Adjacent to the Brunton Theatre   
12970      Leith Walk opposite Dalmeny Street  
9272          Front of new Sick Kids Hospital  

[243 rows x 5 columns]

Vytvoření data frame ‚stations‘ spojením ‚start‘ a ‚end‘ stanic.

!! Průzkum a úprava dat je i o čtení a hledáních chyb, překlepů a jejich nápravě!!

V seznamu jsou stanice se stejným názvem, ale pod různým ID. Některé stanice stanice se stejným názvem se jen mírně liší souřadnicemi, nebo popisem.

IN:

stations = pd.concat([end,start]).drop_duplicates().sort_values(‚station_id‘)
print(„All stations at least once used to start or once to end:“)
stations.sort_values(‚station_id‘)

OUT:

Před pokračováním s analýzou jsem se rozhodl v celém datasetu ujednotit nesrovnalosti s ID čísly a názvy stanic tak, aby nebyly výsledné výpočty zkresleny chybně zadanými daty. 

IN:

edbikes_df.loc[edbikes_df[‚start_station_name‘]==’Brunswick Place‘,[‚start_station_id‘]] = 1769
edbikes_df.loc[edbikes_df[‚end_station_name‘]==’Brunswick Place‘,[‚end_station_id‘]] = 1769
edbikes_df.loc[edbikes_df[‚start_station_name‘]==’Causewayside‘,[‚start_station_id‘]] = 1727
edbikes_df.loc[edbikes_df[‚end_station_name‘]==’Causewayside‘,[‚end_station_id‘]] = 1727
edbikes_df.loc[edbikes_df[‚start_station_name‘]==’Comely Bank Road‘,[‚start_station_id‘]] = 1763
edbikes_df.loc[edbikes_df[‚end_station_name‘]==’Comely Bank Road‘,[‚end_station_id‘]] = 1763
edbikes_df.loc[edbikes_df[‚start_station_name‘]==’Corstorphine Road‘,[‚start_station_id‘]] = 1747
edbikes_df.loc[edbikes_df[‚end_station_name‘]==’Corstorphine Road‘,[‚end_station_id‘]] = 1747
edbikes_df.loc[edbikes_df[‚start_station_name‘]==’Craigleith Road‘,[‚start_station_id‘]] = 1764
edbikes_df.loc[edbikes_df[‚end_station_name‘]==’Craigleith Road‘,[‚end_station_id‘]] = 1764
edbikes_df.loc[edbikes_df[‚start_station_name‘]==’Cramond Foreshore‘,[‚start_station_id‘]] = 1722
edbikes_df.loc[edbikes_df[‚end_station_name‘]==’Cramond Foreshore‘,[‚end_station_id‘]] = 1722
edbikes_df.loc[edbikes_df[‚start_station_name‘]==’Crichton Street‘,[‚start_station_id‘]] = 1017

.

.

.

a podobně dále

Vypsané stanice je možno zobrazit na mapě pomocí souřadnic a vizualizačního nástroje folium.

IN:

import folium
from folium import plugins

m_stations = folium.Map([55.948612, -3.200833],zoom_start=12) # Vytvoří mapu se středem v centru města.
for place, row in stations.iterrows():#  Prochází řádky tabulky stations. 

folium.Marker(row[[‚latitude‘, ‚longitude‘]].values.tolist(),
popup=folium.Popup(f“““Station name: {row[‚station_name‘]}“““),
icon=folium.Icon(icon=“home“, prefix=’fa‘)
).add_to(m_stations)
m_stations

OUT:

Identifikace aktivních a neaktivních stanic.

Aktivní budou stanice, které byly využity alespoň jednou za poslední rok záznamů. 

IN: 

# Vypíše IDs počátečních stanic využitých v posledním roce:

start_active = (edbikes_df.query(„started_at >= ‚2020-06-30‘ or ended_at >= ‚2020-06-30′“)[[‚start_station_id‘]]
.drop_duplicates(subset=’start_station_id‘).rename(columns={‚start_station_id‘:’station_id‘})
)

# Vypíše IDs konečných stanic využitých v posledním roce:

end_active = (edbikes_df.query(„started_at >= ‚2020-06-30‘ or ended_at >= ‚2020-06-30′“)[[‚end_station_id‘]]
.drop_duplicates(subset=’end_station_id‘).rename(columns={‚end_station_id‘:’station_id‘})
)

# Vytvoří soubor s IDs stanic využitých v posledním roce – spojení start_active a end-active:

active_stations = pd.concat([end_active,start_active]).drop_duplicates().sort_values(‚station_id‘)

# Pomocné data frame, ze kterých spojením vznikne soubor s ID stanic, jejich názvy a souřadnicemi:

df_s = stations.reset_index()[[‚station_id‘,’station_name‘,’latitude‘,’longitude‘]].set_index(‚station_id‘)
df_a = active_stations.set_index(‚station_id‘)

# Vznikne dataframe s aktivními stanicemi:

active_complete = df_a.join(df_s).dropna()
active_complete = active_complete.reset_index().drop_duplicates(subset = ‚station_id‘)

# Výpis prvních 6-ti řádků:
active_complete.head(6)

 

OUT:

 

 station_idstation_namelatitudelongitude
1183Waverley Bridge55.951344-3.191421
3189City Chambers55.950109-3.190258
4225Waverley Court55.951734-3.184179
5246Royal Commonwealth Pool55.939000-3.173924
6247Charlotte Square55.952335-3.207101

Aktivní stanice na mapě

IN:

m_active_stations = folium.Map([55.948612, -3.200833],zoom_start=12)
for place, row in active_complete.iterrows():
folium.Marker(row[[‚latitude‘, ‚longitude‘]].values.tolist(),
popup=folium.Popup(f“““Station name: {row[‚station_name‘]}“““),
icon=folium.Icon(icon=“home“, prefix=’fa‘)
).add_to(m_active_stations)
m_active_stations

OUT:

Úprava záladního data setu, aby obsahoval záznamy pouze aktivních stanic.

IN:

edbikes_df = edbikes_df[edbikes_df[‚start_station_id’and’end_station_id‘].isin(active_stations.values[:,0])]

Vytvoření tabulek se součty výpůjček a vratek.

IN:

df = edbikes_df.assign(cnt=0).groupby([‚start_station_id‘,’started_at‘]).count()[[‚cnt‘]]# Vytvoří tabulku s výpůjčkami.
df1 = df.groupby(‚start_station_id‘).sum().rename(columns={‚cnt‘:’sum_borrowings‘}).rename_axis(‚station_id‘)# Tabulka se součty výpůjček dle stanice. 
df2 = edbikes_df.assign(cnt=0).groupby([‚end_station_id‘,’ended_at‘]).count()[[‚cnt‘]]# Vytvoří tabulku s vratkami.
df3 = df2.groupby(‚end_station_id‘).sum().rename(columns={‚cnt‘:’sum_returns‘}).rename_axis(‚station_id‘)# Tabulka se součty vratek dle stanice. 

NZ výše vytvořené tabulky zobrazíme popisnou statistiku výpůjček.

IN:

(df1[[‚sum_borrowings‘]]/1019).describe()

OUT:

sum_borrowings

count 161.000000

mean 2.508299 # Průměrně 2,5 výpůjčky za den

std 2.941329

min0.000981 # Minimálně 1 výpůjčka za 1019 dnů.

25 % 0.219823

50 % 1.424926 # Median 1,4 za den.

75 % 3.866536

max 16.265947 # Maximálně 16 za den.

Popisná statistika vratek.

IN:

(df3[[‚sum_returns‘]]/1019).describe()

OUT:

sum_returns

count 112.000000

mean 3.605680 # Průměrně 3,6 vratek za den.

std 3.316777

min 0.005888 # Minimálně jedna vratka za 170 dnů.

25% 1.361138

50% 2.635427 # Medián 2,64 vratek za den.

75% 4.948724

max 16.345437 # Maximum 16 vratek za den.

Výpis nejfrekventovanějších stanic.

IN:

activity_df = df3.join(df1)# Vytvoření tabulky se součty výpůjček i vratek.
activity_df.fillna(value=0,axis=1,inplace=True) # Vyplnění chybějících hodnot nulou.
activity_df[‚frequency‘]=activity_df.sum_returns+activity_df.sum_borrowings# Přidá sloupec s frekvencí dle stanice.

activity_df[‚day_frequency‘]= (activity_df.frequency/1019).astype(int)# Přidá denní frekvenci.

(

 stations.join(activity_df, on=’station_id‘)[[‚station_id‘,’station_name‘,’frequency‘,’day_frequency‘]].drop_duplicates(subset=’station_id‘).dropna()# Doplní jména stanic.

 .sort_values(‚frequency‘,ascending=False).head(10) # Seřadí dle frekvence sestupně a zobrazí prvních 10.

)

OUT:

Určení kde kola spíše chybí a kde přebývají.

Nejprve do tabulky frekvencí přidáme procentuální podíl vratek.

IN:

activity_df = activity_df.assign(returns_percent=(activity_df.sum_returns/activity_df.frequency*100).round(2))
activity_df.head(10)

OUT:

Funkce, kterou aplikujeme tak, aby řekla, kde kola chybí, nebo se hromadí.

IN:

def usage (x):
if x > 50:
return „rather accumulates“
elif x < 50:
return „rather missing“

Výpis prvních deseti stanic, kde se kola hromadí.

IN:

activity_df.assign(use=activity_df[‚returns_percent‘].apply(usage)).sort_values(‚returns_percent‘,ascending=False).head(10)

OUT:

Výpis prvních deseti stanic, kde kola chybí.

IN:

activity_df.assign(use=activity_df[‚returns_percent‘].apply(usage)).sort_values(‚returns_percent‘).head(10)

OUT:

ZOBRAZENÍ VZDÁLENOSTÍ MEZI STANICEMI.

IN:

!pip install geopy
from geopy.distance import geodesic
from itertools import combinations

combs = list(combinations(stations.index,2)) # Vytvoří list se všemi možnými kombinacemi dvou stanic.

coords = np.array(list(combinations(stations[[‚latitude‘, ‚longitude‘]].values, 2))) # Vytvoří list se všemi možnými kombinacemi souřadnic.

coords = coords.reshape(coords.shape[0],4) # Vytvoří tabulku o 4 sloupcích a počtem řádků jako výše list.

coords = pd.DataFrame(coords) # Z coords array na dataframe.

# Funkce na výpočet vzdáleností:

def geodesic_vec(a, b, c, d):
rs = geodesic( (a, b), (c, d) ).kilometers
return rs

distances = list()
for data,row in coords.iterrows():
dists = np.round(geodesic_vec(row[0],row[1],row[2],row[3]),2)
distances.append(dists) # List se vzdálenostmi.

distances_df = pd.DataFrame(distances,pd.Index(combs,names=[‚City1′,’City2‘]),columns=[‚distance‘]) # Tabulka vzdáleností.

distances_df

OUT:

DOBA TRVÁNÍ VÝPŮJČEK

IN:

duration_df = edbikes_df[[‚duration‘]].assign(duration_min=round(edbikes_df.duration/60))

# Vytvoří dataset s dobou trvání výpůjček v minutách.

duration_df[[‚duration_min‘]].describe() # Deskriptivní statistika trvání výpůjček.

OUT:

Určení odlehlých hodnot před zobrazením histogramu doby výpůjček:

1) Určení interquartile range(IQR): (42 – 10) * 1,5 = 48
2) Přičtení IQR k 75 percentilu: 48 + 42 = 90
3) Všechny hodnoty nad 90 jsou odlehlé.

IN:

import matplotlib.pyplot as plt
plt.hist(duration_df[duration_df[‚duration_min‘].isin(range(5,91))][[‚duration_min‘]],bins = 6)
plt.xlabel(‚minutes‘)
plt.ylabel(‚count‘)
plt.title(‚DURATION IN MINUTES‘)
plt.grid(True)
plt.show()

OUT:

POČET VÝPŮJČEK ZA DEN

IN:

df4 = edbikes_df[[‚started_at‘]]# Vybere sloupec s začátky výpůjček.
df4 = df4.assign (started_at_day = pd.to_datetime(df4[‚started_at‘]).dt.date) # Přidá sloupec ve formátu data.
df4 = df4[[‚started_at_day‘]].assign(borrowings_count=0).groupby(‚started_at_day‘).count()# Přidápočtyvýpůjčekzaden.
df4.index = pd.to_datetime(df4.index) # Změní formát indexu.
df4

OUT:

VÝVOJ POPTÁVKY V ČASE

IN:

hour_df = edbikes_df.assign(started_at_day = pd.to_datetime(edbikes_df[‚started_at‘]).dt.date, hours = pd.to_datetime(edbikes_df[‚started_at‘]).dt.hour) # Přidá sloupce se dny a hodinami.
day_df = hour_df[hour_df[‚hours‘].isin(range(6,19))]# Vybere jen denní dobu.
day_df = day_df.groupby(‚started_at_day‘).count()[[‚hours‘]]# Vypočítá sumu výpůjček během denní doby.

night_df = hour_df[~hour_df[‚hours‘].isin(range(6,19))] # Vybere noční dobu.
night_df = night_df.groupby(‚started_at_day‘).count()[[‚hours‘]]# Vypočítá výpůjčky během noci.

fig,ax = plt.subplots(figsize=(19,4)) # Vytvoří prázdný graf.
ax.plot(day_df) # Přidá počty denních výpůjček.
ax.plot(night_df) # Přidá počty nočních výpůjček.
ax.legend(labels = [‚day‘,’night‘]) 
ax.grid()
plt.show()

OUT:

PŮJČUJÍ SI LIDÉ KOLA VÍCE O VÍKENDU NEBO PŘES TÝDEN?

IN:

weekday_df = (edbikes_df.assign(started_at_day = pd.to_datetime(edbikes_df[‚started_at‘])
.dt.date, day_of_week = pd.to_datetime(edbikes_df[‚started_at‘]).dt.dayofweek)# Přidá číslo dne v týdnu.
)
week_df = weekday_df[weekday_df[‚day_of_week‘].isin(range(0,5))] # Vybere jen pracovní dny.
week_df = week_df.groupby(‚started_at_day‘).count()[[‚started_at‘]] # Vypočítá výpůjčky během pracovních dnů.
weekend_df = weekday_df[~weekday_df[‚day_of_week‘].isin(range(0,5))]# Vybere jen víkendy.
weekend_df = weekend_df.groupby(‚started_at_day‘).count()[[‚started_at‘]] # Vypočítá výpůjčky během víkendu.
# Vytiskne výsledky:
print(‚Rental daily average working days: ‚)
print(‚\n‘,week_df.describe().iloc[1,0])
print(‚\n‘,’Rental daily average weekends: ‚)
print(‚\n‘,weekend_df.describe().iloc[1,0])
print(‚\n‘,’Daily borrowings during weekends are slightly higher than during working days.‘)

OUT:

Rental daily average working days: 

 387

 Rental daily average weekends: 

 443

 Daily borrowings during weekends are slightly higher than during working days.

NAČTENÍ DAT O POČASÍ V EDINBURGHU

IN:

edweather_df = pd.read_sql(‚edinburgh_weather‘,conn_string)
edweather_df[‚date‘] = pd.to_datetime(edweather_df[‚date‘])# Změní formát data.
edweather_df = edweather_df.set_index(‚date‘)# Datum do indexu.
edweather_df

OUT:

V tabulce dat o počasí nechybí žádné hodnoty.

IN:

edweather_df.isna().sum()

OUT:

Před dalším zpracováním dat o počasí změníme všechny údaje na numerické hodnoty. 

IN:

Funkce na přiřazení stupně viditelnosti:
def vis (x):
if x == ‚Excellent‘:
return 4
elif x == ‚Good‘:
return 3
elif x == ‚Average‘:
return 2
else:
return 1

Změna na numerické hodnoty:
edweather_df = (edweather_df.assign(temp_celsius = edweather_df.temp.str.extract(„([-+]?\d+)“).astype(int),
feels_celsius = edweather_df.feels.str.extract(„([-+]?\d+)“).astype(int),
wind_kmh = edweather_df.wind.str.extract(„([-+]?\d+)“).astype(int),
gust_kmh = edweather_df.gust.str.extract(„([-+]?\d+)“).astype(int),
rain_mm = edweather_df.rain.str.extract(„([-+]?\d*\.\d+|[-+]?\d+)“).astype(float),
humidity_percent = edweather_df.humidity.str.extract(„([-+]?\d+)“).astype(int),
cloud_percent = edweather_df.cloud.str.extract(„([-+]?\d+)“).astype(int),
pressure_mb = edweather_df.pressure.str.extract(„([-+]?\d+)“).astype(int),
vis_point = edweather_df.vis.apply(vis))
)[[‚time‘,’temp_celsius‘, ‚feels_celsius‘, ‚wind_kmh‘, ‚gust_kmh‘, ‚rain_mm‘, ‚humidity_percent‘, ‚cloud_percent‘, ‚pressure_mb‘, ‚vis_point‘]]

edweather_df

OUT:

Deskriptivní statistika jednotlivých měření počasí. Výsledky:

  • rozmezí teplot od -4 do +27°C,
  • maximální rychlost větru 54 km/h,
  • maximální srážky 23,4 mm.
    Data potvrzují, že za období měření bylo v Edinburghu mírné počasí bez extrémních srážek a větru.

IN:

edweather_df.describe()

OUT:

Úprava na denní průměrné hodnoty měření.

IN:

edweather_df = edweather_df.groupby(‚date‘).mean()

edweather_df

OUT:

Abychom otestovali korelace mezi počtem výpůjček a počasím, přidáme počty výpůjček ke každému dni.

IN:

edweather_df = df4.join(edweather_df,how=’inner‘)
edweather_df

OUT:

Korelační koeficienty. Ovlivňuje počasí počet výpůjček?

IN:

print(„Correlation between temperature and rentals: „)
print(‚\n‘,edweather_df[‚borrowings_count‘].corr(edweather_df[‚feels_celsius‘]).round(2))

 

OUT:

Correlation between temperature and rentals: 

 0.43

Efekt teploty během hlavní sezony je menší.

IN:

start_date = ‚2020-06-01‘
end_date = ‚2020-08-30‘
selection = (edweather_df.index>=start_date)&(edweather_df.index<=end_date)
season_df = edweather_df.loc[selection]
print(„Correlation between temperature and rentals from June to end August: „)
print(‚\n‘,season_df[‚borrowings_count‘].corr(season_df[‚feels_celsius‘]).round(2))

OUT:

Correlation between temperature and rentals from June to end August: 

 0.36

Ostatní vlivy počasí.

IN:

print(„Correlation between wind speed and rentals: „)
print(‚\n‘,edweather_df[‚borrowings_count‘].corr(edweather_df[‚wind_kmh‘]).round(2))

print(„Correlation between gusty wind and rentals: „)
print(‚\n‘,edweather_df[‚borrowings_count‘].corr(edweather_df[‚gust_kmh‘]).round(2))

print(„Correlation between rain fall and rentals: „)
print(‚\n‘,edweather_df[‚borrowings_count‘].corr(edweather_df[‚rain_mm‘]).round(2))

print(„Correlation between humidity and rentals: „)
print(‚\n‘,edweather_df[‚borrowings_count‘].corr(edweather_df[‚humidity_percent‘]).round(2))

print(„Correlation between clouds nad rentals: „)
print(‚\n‘,edweather_df[‚borrowings_count‘].corr(edweather_df[‚cloud_percent‘]).round(2))

print(„Correlation between atmospheric pressure and rentals: „)
print(‚\n‘,edweather_df[‚borrowings_count‘].corr(edweather_df[‚pressure_mb‘]).round(2))

print(„Correlation between visibility factor and rentals: „)
print(‚\n‘,edweather_df[‚borrowings_count‘].corr(edweather_df[‚vis_point‘]).round(2))

OUT:

Correlation between wind speed and rentals: 

 -0.2

Correlation between gusty wind and rentals: 

 -0.24

Correlation between rain fall and rentals: 

 -0.06

Correlation between humidity and rentals: 

 -0.21

Correlation between clouds nad rentals: 

 -0.06

Correlation between atmospheric pressure and rentals: 

 0.11

Correlation between visibility factor and rentals: 

 0.06