import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import os
from IPython.core.pylabtools import figsize
%matplotlib inline
figsize(10, 8)
plt.style.use('Solarize_Light2')
os.chdir('D:\Data\Projects\Klassifikation\Klassifikation_West Nile Virus')
pd.set_option('display.max_columns', 500)
df = pd.read_csv('weather.csv')
df.columns
df.dtypes.sort_values()
df.Date = pd.to_datetime(df.Date)
Spalten, deren dtype object ist, die aber eigenlich numerisch sein sollten, haben wahrscheinlich strings für fehlende Werte oder andere Bedeutungen, weswegen die Umwandlung nicht funktioniert.
for col in ['Depart', 'Tavg', 'WetBulb', 'Heat', 'Cool', 'PrecipTotal', 'StnPressure',
'SeaLevel', 'AvgSpeed', 'Sunrise', 'Sunset']:
print('***'+col.upper()+'***')
print(df[col].str.findall('(\D)').value_counts())
df.columns[df.isin(['T', 'M', '-']).any()]
df.PrecipTotal.str.contains('T').sum()
Es gibt 318 T und 2 M.
T = Trace, M = Missing Value.
Ersetze T mit 0.0001
T kommt in dieser Form vor: ' , , T' (zwei Leerzeichen, dann das T)
M werden später mit nan ersetzt.
Die 0.0001 muss als string angegeben werden, sonst funktioniert die Methode replace nicht.
df.PrecipTotal = df.PrecipTotal.str.replace(' T', '0.0001')
df.PrecipTotal.value_counts().head()
df = df.drop(['SnowFall','Water1', 'Depth' ], axis = 1)
Mit Errors = coerce werden nicht umwandelbare Werte zu nans
cols = ['Depart', 'Tavg','WetBulb', 'Heat', 'Cool', 'PrecipTotal', 'StnPressure', 'SeaLevel', 'AvgSpeed']
df[cols] = df[cols].apply(pd.to_numeric, errors='coerce')
missing = pd.DataFrame(df.isnull().sum()).rename(columns = {0: 'total'})
missing['percent'] = missing['total'] / len(df)*100
missing = missing[missing.total != 0]
missing = missing.sort_values('percent', ascending = False)
missing
df.Tavg = ((df.Tmax + df.Tmin)/2).astype(int)
Da, wo die Hälfte der Werte fehlen, wurden sie nur in einer Station dokumentiert. Sie können von Station 1 auf Station 2 übertragen werden.
Definition, um Werte von Station 2 mit den Werten aus Station 1 vom gleichen Datum zu ersetzen. (Eigenlich unnötig, da wir später den Wert aus STation 1 nehmen werden, wo die Werte beider Stationen gleich sind und ansonsten den Durchschnitt beider STationen berechnen werden, aber der Vollständigkeit halber wird es gemacht)
# Sunrise und Sunset sind Uhrzeiten. Die Werte aus Station 1 werden auch für Station 2 gesetzt
def sel1(df, col):
for i, val in enumerate(df[col]):
if val == '-':
date = df.loc[i, 'Date']
hour = df.loc[(df.Date == date) & (df.Station == 1), col]
hour = hour.values[0]
df.loc[i, col] = hour
return(df)
# Für numerische Werte, bei denen ein 'M' für fehlende Werte stand
def sel(df, col):
for i, val in enumerate(df[col]):
if np.isnan(val):
date = df.loc[i, 'Date']
hour = df.loc[(df.Date == date) & (df.Station == 1), col]
hour = hour.values[0]
df.loc[i, col] = hour
return(df)
for i in ['Sunrise', 'Sunset']:
sel1(df, i)
df = sel(df, 'Depart')
Da später die Durschnittswerte der beiden Stationen berechnet werden, werden alle Werte benötigt, daher ist ein Entfernen der Beobachtungen mit fehlenden Werten nicht möglich. Die fehlenden Werte werden stattdessen mit Pandas interpoliert.
for column in ['Heat', 'Cool', 'SeaLevel', 'WetBulb', 'StnPressure', 'AvgSpeed', 'PrecipTotal']:
df[column] = df[column].fillna(df[column].mean(skipna = True))
missing = pd.DataFrame(df.isnull().sum()).rename(columns = {0: 'total'})
missing['percent'] = missing['total'] / len(df)*100
missing = missing[missing.total != 0]
missing = missing.sort_values('percent', ascending = False)
missing
df.dtypes.sort_values()
df.describe()
import plotly_express as px
from plotly.offline import init_notebook_mode, iplot
import plotly.graph_objs as go
import plotly.plotly as py
from plotly import tools
import plotly.figure_factory as ff
init_notebook_mode(connected=True)
df.Station.value_counts()
a = df.loc[df.Date.dt.year == 2007]
figsize(10, 8)
ax = plt.subplot()
a.groupby(a.Date.dt.month)['Tavg'].mean().plot()
a.groupby(a.Date.dt.month)['Tmin'].mean().plot()
a.groupby(a.Date.dt.month)['Tmax'].mean().plot()
ax.set_xlabel('Date', fontsize=18);
ax.set_ylabel('Temperature (°F)', fontsize=18);
ax.set_title('Temperatures in 2007', fontsize=20);
ax = plt.subplot()
ax.plot_date(a.Date, a.Tavg)
ax.plot_date(a.Date, a.Tmax);
ax.plot_date(a.Date, a.Tmin);
ax.set_xlabel('Date', fontsize=18);
ax.set_ylabel('Temperature (°F)', fontsize=18);
ax.set_title('Weather in 2007');
a[['Date','Tavg']].set_index('Date').plot()
trace_high = go.Scatter(
x=a.Date,
y=a['Tmax'],
name = "Tmax",
line = dict(color = 'pink'),
opacity = 0.9)
trace_low = go.Scatter(
x=a.Date,
y=a['Tmin'],
name = "Tmin",
line = dict(color = 'lightblue'),
opacity = 0.9)
data = [trace_high,trace_low]
layout = go.Layout(
template= 'plotly_dark',
title = "Temperatures from May to October 2007",
xaxis=dict(
range = ['2007-04-01','2007-11-30'],
title='Date',
titlefont=dict(
family='Arial, sans-serif',
size=18,
color='lightgrey'),
showticklabels=True,
tickangle=0,
tickfont=dict(
family='Old Standard TT, serif',
size=14,
color='white'),
exponentformat='e',
showexponent='all'),
yaxis=dict(
title='Degrees Fahrenheit',
titlefont=dict(
family='Arial, sans-serif',
size=18,
color='lightgrey'
),
showticklabels=True,
tickangle=0,
tickfont=dict(
family='Old Standard TT, serif',
size=14,
color='white'
),
exponentformat='e',
showexponent='all'
)
)
fig = dict(data=data, layout=layout)
iplot(fig)
trace1 = go.Bar(x=a['Date'],
y=a['Tmax'],
marker = dict(color = 'red'),
name = 'Tmax')
trace2 = go.Bar(x=a['Date'],
y=a['Tmin'],
marker = dict(color = 'blue'),
name = 'Tmin')
data1 = [trace1, trace2]
layout1 = go.Layout(title = "Temperatures of Summer/Autumn 2007",
barmode='group')
fig = dict(data=data1, layout=layout1)
iplot(fig)
# Zwei DF für je station 1 und 2
# reset index, weil der sonst nur aus jedem 2. besteht
station_1 = df[df['Station'] == 1].reset_index()
station_2 = df[df['Station'] == 2].reset_index()
# Df mit dem Datum von Station 1 und Daten, die nur in Station 1 dokumentiert worden waren
weather_new = pd.DataFrame()
weather_new['Date'] = station_1.Date
weather_new['Sunrise'] = station_1.Sunrise
weather_new['Sunset'] = station_1.Sunset
weather_new['Depart'] = station_1.Depart
# Für jede Spalte den Durchschnitt der beiden Stationen hinzufügen
for col in ['Tmax', 'Tmin', 'Tavg', 'DewPoint',
'WetBulb', 'Heat', 'Cool',
'PrecipTotal', 'StnPressure', 'SeaLevel', 'ResultSpeed', 'ResultDir',
'AvgSpeed']:
weather_new[col] = (station_1[col] + station_2[col])*0.5
weather_new.head()
df.Date.dt.year.value_counts().sort_index()
Da Moskitos einen Zyklus haben, und von bestimmten Wetterfaktoren beeinflusst werden, aber mit einem Lag, sollten diese Lags aufgenommen werden.
Regen-Pfützen-Eiablage-Schlüpfen
Warmes Wetter- mehr
Windrichtung- driften der Population
Windstärke- Aktivität der Mücken
Druckunterschiede- Flughöhe
weather_new['Rain_prev']= 0
weather_new.loc[weather_new.Date.dt.year == 2009, 'Rain_prev'] = weather_new.loc[weather_new.Date.dt.year == 2008, 'PrecipTotal'].sum()
weather_new.loc[weather_new.Date.dt.year == 2011, 'Rain_prev'] = weather_new.loc[weather_new.Date.dt.year == 2010, 'PrecipTotal'].sum()
weather_new.loc[weather_new.Date.dt.year == 2013, 'Rain_prev'] = weather_new.loc[weather_new.Date.dt.year == 2012, 'PrecipTotal'].sum()
Es wird nur das Wetter der Jahre verwendet, die auch in train sind. Schön wäre ein Jahr vor dem ersten Jahr im train Satz, da dies eine Population beeinflussen kann. Flag, falls das Jahr davor verregnet war.
wny = weather_new.loc[(weather_new.Date.dt.year == 2007)|
(weather_new.Date.dt.year == 2009) |
(weather_new.Date.dt.year == 2011) |
(weather_new.Date.dt.year == 2013)]
wny.Date.dt.year.value_counts()
nein! Damit wüßte ich dann schon im Voraus etwas, das ich nicht wissen kann, wenn ich Mitten im Sommer die Moskitozahl vorhersagen soll. Nimm stattdessen die Summe der Tage bis zum Zeitpunkt der Beobachtung!
d = 0
hot = []
for i in wny.Tavg:
if 77 <i< 86:
d+=1
hot.append(d)
else:
d=0
hot.append(d)
wny['Hot_Days'] = hot
wny.Hot_Days.value_counts()
wny['Rain_lag_3'] = wny.PrecipTotal.shift(3)
wny['Rain_lag_8'] = wny.PrecipTotal.shift(8)
wny['Rain_lag_15'] = wny.PrecipTotal.shift(15)
wny['Wind_lag_3'] = wny.AvgSpeed.shift(3)
wny['Wind_lag_8'] = wny.AvgSpeed.shift(8)
wny['Wind_lag_15'] = wny.AvgSpeed.shift(15)
wny.Sunrise = wny.Sunrise.astype(int)
wny.Sunset = wny.Sunset.astype(int)
wny['Daylen'] = wny.Sunset - wny.Sunrise
wny.head()
wny.to_csv('weather_final.csv', sep=',', encoding='utf-8', index=False)