import numpy as np # pip3 install numpy import pandas as pd # pip3 install pandas import matplotlib.pyplot as plt import scipy as sp from scipy import stats ### a) Einlesen der Quelldaten # Pandas-Methode read_csv() zum Einlesen nutzen, wobei die Spalte namens "id" ausgelassen wird gewuenschteSpalten = ["battery_power", "bluetooth", "dual_sim", "4G", "int_memory", "ram"] df = pd.read_csv('mobile_device_data.csv', usecols=gewuenschteSpalten) # Print inkl. Dataframe-Methode head() aufrufen # Parameter n: Ausgabe der ersten 12 Zeilen (Zeile 0 bis 11 = 12 Zeilen) print(df.head(n=12)) # Ausgabe: # battery_power bluetooth dual_sim 4G int_memory ram # 0 1043 1.0 1 0 5 3476 # ... ... ... ... ... ... ... # 11 1343 0.0 0 1 34 3911 ### b) Bereinigen # Dataframe enthält verschiedene Arten nicht auswertbarer Zellen: # 1. Zellen in denen vorher schon NaN (NotANumber) steht # 2. Zellen, in denen ein leerer String steht (' ') # -> umwandeln von (' ') in "NaN", per DataFrame-Methode replace() df.replace(to_replace=' ', value=np.nan, inplace=True) # 1. und 2. lassen sich jetzt auf die gleiche Weise wie folgt ausgeben, # und es werden 4 Zeilen gefunden, in denen das Bluetooth Feld "NaN" ist, # und insgesamt 6 Zeilen, in denen das 4G, int_memory und ram Feld "NaN" sind: # print(df.isna().sum()) # Ausgabe: # battery_power 0 # bluetooth 4 # dual_sim 0 # 4G 2 # int_memory 2 # ram 2 # Dataframe-Methode "dropna" aufrufen, um solche Einträge zu löschen: # Parameter axis=0 : Zeile wird gelöscht # Parameter how='any' : Zum Löschen genügt eine einzelne leere Zelle # Parameter inplace=True : Die Operation wird direkt auf das DataFrame angewendet df.dropna(axis=0, how='any', inplace=True) # Nach dieser Änderung sind nur noch 200 Zeilen im DataFrame print(len(df.index)) # Ausgabe: # 200 ### c) Univariate Analyse # Die Datentypen der gewünschten Merkmale werden nicht von vornherein alle als Ganzzahlen (Integer) # interpretiert (vgl. print(df.info()) ), daher erst in solche umwandeln. # Wenn man das nicht macht, kann .describe() nicht ordentlich mit gemischten Spaltentypen umgehen. # Die Beispielausgabe wäre sonst: "mean 1264.560000 NaN NaN" dfMetrischeMerkmale = df[["battery_power", "int_memory", "ram"]].astype(int) dfUnivariateAnalyse = dfMetrischeMerkmale[["battery_power", "int_memory", "ram"]].describe(include='all', percentiles=[0.2, 0.5, 0.8]) dfUnivariateAnalyse.to_csv('UnivariateAnalyse.csv') # Ausgabe: # battery_power int_memory ram # count 200.000000 200.000000 200.000000 # mean 1264.560000 33.485000 2153.125000 # std 441.550223 17.795595 1140.426372 # min 504.000000 2.000000 263.000000 # 20% 857.600000 16.000000 870.800000 # 50% 1249.500000 33.000000 2172.500000 # 80% 1721.400000 51.000000 3317.600000 # max 1999.000000 64.000000 3976.000000 ### d) Balkendiagramme # Arbeitstabelle erzeugen, die nur die Spalten der nominalen Merkmale enthält: # inkl. Typenumwandlung zur Ganzzahl: .astype(int) dfNominaleMerkmale = df[["bluetooth", "dual_sim", "4G"]].astype(int) # print(df["bluetooth"].value_counts()) # Jetzt Abwechselnd: # ___Yes = Extrahieren der Datensätze mit Merkmalsausprägung 1 (yes) # anzahl___Yes = Anzahl der Datensätze ermitteln # ___No = Extrahieren der Datensätze mit Merkmalsausprägung 0 (no) # anzahl___No = Anzahl der Datensätze ermitteln bluetoothYes = dfNominaleMerkmale.loc[dfNominaleMerkmale['bluetooth'] == 1] anzahlBluetoothYes = bluetoothYes.shape[0] # Anzahl ermitteln bluetoothNo = dfNominaleMerkmale.loc[dfNominaleMerkmale['bluetooth'] == 0,] anzahlBluetoothNo = bluetoothNo.shape[0] # Anzahl ermitteln dualSimYes = dfNominaleMerkmale.loc[dfNominaleMerkmale['dual_sim'] == 1] anzahlDualSimYes = dualSimYes.shape[0] # Anzahl ermitteln dualSimNo = dfNominaleMerkmale.loc[dfNominaleMerkmale['dual_sim'] == 0] anzahlDualSimNo = dualSimNo.shape[0] # Anzahl ermitteln g4Yes = dfNominaleMerkmale.loc[dfNominaleMerkmale['4G'] == 1] anzahl4GYes = g4Yes.shape[0] # Anzahl ermitteln g4No = dfNominaleMerkmale.loc[dfNominaleMerkmale['4G'] == 0] anzahl4GNo = g4No.shape[0] # Anzahl ermitteln # Neues Dataframe erzeugen, das je Merkmal die Anzahl der Yes/No Ausprägungen abbildet anzahlYes = [anzahlBluetoothYes, anzahlDualSimYes, anzahl4GYes] anzahlNo = [anzahlBluetoothNo, anzahlDualSimNo, anzahl4GNo] index = ["bluetooth", "dual_sim", "4G"] # Beschriftung der indeX-Achse dfAnzahlYesNo = pd.DataFrame({'yes': anzahlYes, 'no': anzahlNo}, index=index) # print(dfAnzahlYesNo) # yes no # bluetooth 104 96 # dual_sim 109 91 # 4G 90 110 # Für dieses Dataframe ein Balkendiagramm erzeugen, mit Rotation=0 dfAnzahlYesNo.plot.bar() #plt.show() ### e) Korrellationen nach Pearson und Lineare Regression zweier Merkmale print(dfMetrischeMerkmale.corr(method="pearson")) # Ausgabe: # battery_power int_memory ram # battery_power 1.000000 0.050449 -0.069141 # int_memory 0.050449 1.000000 0.047475 # ram -0.069141 0.047475 1.000000 # -> ram und battery_power korrelieren am Stärksten, wenn auch negativ: # Per Modul SciPy Stats: Methode der kleinsten Quadrate für die Lineare Regression nutzen werteListeX = dfMetrischeMerkmale["ram"] werteListeY = dfMetrischeMerkmale["battery_power"] regrErgebnisse = sp.stats.linregress(werteListeX, werteListeY) steigung = round(regrErgebnisse.slope, 4) yAchsAbschn = round(regrErgebnisse.intercept, 4) arrYpredicted = steigung * werteListeX + yAchsAbschn # using y = m*x + n, calculate every single Y-Value fitting the regression Lines X-Values print("Regressionsgleichung:", "y =", steigung, "* x +", yAchsAbschn) # Plot Linear Regression Line plt.clf() # Clear last plot image plt.plot(werteListeX, arrYpredicted, label='Lin Regression', color='red', linestyle='solid') # https://scriptverse.academy/tutorials/python-matplotlib-plot-straight-line.html # Show Plot Image plt.xlabel('ram', color='black') plt.ylabel('battery_power', color='black') #plt.xlim([0,50]) # set x-Axis View Range,[from,to] plt.scatter(werteListeX, werteListeY) #plt.show() ### f) Skalierung in [0, 1] dfMetrischeMerkmale["battery_power_skaliert"] = dfMetrischeMerkmale["battery_power"] / dfMetrischeMerkmale["battery_power"].max() dfMetrischeMerkmale["int_memory_skaliert"] = dfMetrischeMerkmale["int_memory"] / dfMetrischeMerkmale["int_memory"].max() dfMetrischeMerkmale["ram_skaliert"] = dfMetrischeMerkmale["ram"] / dfMetrischeMerkmale["ram"].max() # print(dfMetrischeMerkmale) # battery_power int_memory ... int_memory_skaliert ram_skaliert # 0 1043 5 ... 0.078125 0.874245 # 1 841 61 ... 0.953125 0.979628 # 2 1807 27 ... 0.421875 0.602616 # ... ### g) Boxplots plt.clf() # Clear last plot image plt.close('all') plt.boxplot(dfMetrischeMerkmale["battery_power"], showfliers=True) plt.show() #dfMetrischeMerkmale.boxplot("battery_power", showfliers=True, backend="matplotlib") #plt.show() plt.clf() # Clear last plot image dfMetrischeMerkmale.boxplot("int_memory", showfliers=True) plt.show() plt.clf() # Clear last plot image dfMetrischeMerkmale.boxplot("ram", showfliers=True) plt.show()