預備知識-python核心用法常用數據分析庫(下)


2、預備知識-python核心用法常用數據分析庫(下)

概述

Python 是當今世界最熱門的編程語言,而它最大的應用領域之一就是數據分析。在python眾多數據分析工具中,pandas是python中非常常用的數據分析庫,在數據分析,機器學習,深度學習等領域經常被使用。使用 Pandas 我們可以 Excel/CSV/TXT/MySQL 等數據讀取,然后進行各種清洗、過濾、透視、聚合分析,也可以直接繪制折線圖、餅圖等數據分析圖表,在功能上它能夠實現自動化的對大文件處理,能夠實現 Excel 的幾乎所有功能並且更加強大。

本實驗將通過實戰的方式,介紹pandas數據分析庫的基本使用,讓大家在短時間內快速掌握python的數據分析庫pandas的使用,為后續項目編碼做知識儲備

實驗環境

  • Python 3.7
  • Pycharm

任務二:Pandas數據分析實戰-1

【任務目標】

本任務主要目標為使用pandas進行數據分析實戰,在實戰過程中帶大家了解pandas模塊的一下功能:

  • 了解數據
  • 分析數據問題
  • 清洗數據
  • 整合代碼

【任務步驟】

1、准備工作

打開CMD窗口后,執行如下命令,打開jupyter notebook編輯器

jupyter notebook

成功執行以上命令后,系統將自動打開默認瀏覽器,如下圖所示:

img

成功打開瀏覽器后,按如下流程創建 notebook 文件

img

對新建notebook進行重命名操作

img

img

2、notebook 文件新建完成后,接下來在新建的 notebook 中編寫代碼

  • 了解數據

在處理任何數據之前,我們的第一任務是理解數據以及數據是干什么用的。我們嘗試去理解數據的列/行、記錄、數據格式、語義錯誤、缺失的條目以及錯誤的格式,這樣我們就可以大概了解數據分析之前要做哪些“清理”工作。

本次我們需要一個 patient_heart_rate.csv 的數據文件,這個數據很小,可以讓我們一目了然。這個數據是 csv 格式。數據是描述不同個體在不同時間的心跳情況。數據的列信息包括人的年齡、體重、性別和不同時間的心率。

  • 加載數據即查看數據集
import pandas as pd
df = pd.read_csv('data/patient_heart_rate.csv')
df.head()

運行結果如下:

img

分析數據問題

  1. 沒有列頭
  2. 一個列有多個參數
  3. 列數據的單位不統一
  4. 缺失值
  5. 重復數據
  6. ASCII 字符
  7. 有些列頭應該是數據,而不應該是列名參數

3、清洗數據

3.1、 沒有列頭

如果我們拿到的數據像上面的數據一樣沒有列頭,Pandas 在讀取 csv 提供了自定義列頭的參數。下面我們就通過手動設置列頭參數來讀取 csv,代碼如下:

import pandas as pd
column_names= ['id', 'name', 'age', 'weight','m0006',
                'm0612','m1218','f0006','f0612','f1218']
df = pd.read_csv('data/patient_heart_rate.csv', names = column_names)
df.head()

運行結果如下:

img

上面的結果展示了我們自定義的列頭。我們只是在這次讀取 csv 的時候,多了傳了一個參數 names = column_names,這個就是告訴 Pandas 使用我們提供的列頭。

4、一個列有多個參數

在數據中不難發現,Name 列包含了兩個參數 Firtname 和 Lastname。為了達到數據整潔目的,我們決定將 name 列拆分成 Firstname 和 Lastname

使用 str.split(expand=True),將列表拆成新的列,再將原來的 Name 列刪除

df[['first_name','last_name']] = df['name'].str.split(expand=True)
df.drop('name', axis=1, inplace=True)
df.head()

運行結果如下:

img

5、列數據的單位不統一

如果仔細觀察數據集可以發現 Weight 列的單位不統一。有的單位是 kgs,有的單位是 lbs

lbs_weight_s = df[df.weight.str.contains("lbs").fillna(False)]['weight']
lbs_weight_s = lbs_weight_s.apply(lambda lbs:  "%.2fkgs" % (float(lbs[:-3])/2.2)  )
df.loc[lbs_weight_s.index,'weight'] = lbs_weight_s

運行結果如下:

image.png

6、缺失值處理

在數據集中有些年齡、體重、心率是缺失的。我們又遇到了數據清洗最常見的問題——數據缺失。一般是因為沒有收集到這些信息。我們可以咨詢行業專家的意見。典型的處理缺失數據的方法:

  • 刪:刪除數據缺失的記錄
  • 贗品:使用合法的初始值替換,數值類型可以使用 0,字符串可以使用空字符串“”
  • 均值:使用當前列的均值
  • 高頻:使用當前列出現頻率最高的數據
  • 源頭優化:如果能夠和數據收集團隊進行溝通,就共同排查問題,尋找解決方案。

7、重復數據處理

有的時候數據集中會有一些重復的數據,執行以下代碼觀察數據集前10條數據

df.head(10)

運行結果如下:

img

觀察以上結果,可以發現在我們的數據集中也存在重復的數據,如下

img

首先我們校驗一下是否存在重復記錄。如果存在重復記錄,就使用 Pandas 提供的 drop_duplicates() 來刪除重復數據。

df.drop_duplicates(['first_name','last_name'],inplace=True)
df.head(10)

運行結果如下:

img

刪除weight字段重復的數據

df.drop_duplicates(['weight'],inplace=True)
df.head(10)

運行結果如下

img

8、 非ASCII 字符

在數據集中 Fristname 和 Lastname 有一些非 ASCII 的字符。

處理非 ASCII 數據方式有多種

  • 刪除
  • 替換
  • 僅僅提示一下

我們使用刪除的方式:

df['first_name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True)df['last_name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True)df.head()

運行結果如下:

img

9、有些列頭應該是數據,而不應該是列名參數

有一些列頭是有性別和時間范圍組成的,這些數據有可能是在處理收集的過程中進行了行列轉換,或者收集器的固定命名規則。這些值應該被分解為性別(m,f),小時單位的時間范圍(00-06,06-12,12-18)

sorted_columns = ['id','age','weight','first_name','last_name']df = pd.melt(df,             id_vars=sorted_columns,             var_name='sex_hour',             value_name='puls_rate')df = df[df.puls_rate != '-'].dropna()df = df.sort_values(['id','first_name','last_name']).reset_index()def split_sex_date(sex_hour):    sex = sex_hour[:1]    if 'f' == sex:        sex = '女'    elif 'm' == sex:        sex = '男'    hour = sex_hour[1:]    return pd.Series([sex,hour])df[['sex','hour']] = df.sex_hour.apply(split_sex_date)df.drop('sex_hour',axis=1)

運行結果如下:

image.png

任務三:Pandas數據分析實戰-2

【任務目標】

本任務主要目標為使用pandas進行數據分析實戰,在實戰過程中帶大家了解pandas模塊的一下功能:

  • 日期的處理
  • 字符編碼的問題

【任務步驟】

1、參考【任務一】第1步中操作,在jupyter notebook編輯中重新新建一個notebook 文件,命名為 pandas-data-processing-3,如下圖所示:

img

2、預覽數據

這次我們使用 Artworks.csv,我們選取 100 行數據來完成本次內容。具體步驟:

  • 導入Pandas
  • 讀取 csv 數據到 DataFrame(要確保數據已經下載到指定路徑)

DataFrame 是 Pandas 內置的數據展示的結構,展示速度很快,通過 DataFrame 我們就可以快速的預覽和分析數據。代碼如下:

import pandas as pddf = pd.read_csv('./data/Artworks.csv').head(100)df.head(10)

運行結果如下:

img

2、統計日期數據

我們仔細觀察一下 Date 列的數據,有一些數據是年的范圍(1976-1977),而不是單獨的一個年份。在我們使用年份數據畫圖時,就不能像單獨的年份那樣輕易的畫出來。我們現在就使用 Pandas 的 value_counts() 來統計一下每種數據的數量。

首先,選擇要統計的列,並調用 value_counts():

df['Date'].value_counts()

運行結果如下:

img

3、日期數據問題

Date 列數據,除了年份是范圍外,還有三種非正常格式。下面我們將這幾種列出來:

  • 問題一,時間范圍(1976-77)
  • 問題二,估計(c. 1917,1917 年前后)
  • 問題三,缺失數據(Unknown)
  • 問題四,無意義數據(n.d.)

接下來我們會處理上面的每一個問題,使用 Pandas 將這些不規則的數據轉換為統一格式的數據。

問題一和二是有數據的只是格式上欠妥當,問題三和四實際上不是有效數據。針對前兩個問題,我們可以通過代碼將據格式化來達到清洗的目的,然而,后兩個問題,代碼上只能將其作為缺失值來處理。簡單起見,我們將問題三和四的數據處理為0。

處理問題一

問題一的數據都是兩個年時間范圍,我們選擇其中的一個年份作為清洗之后的數據。為了簡單起見,我們就使用開始的時間來替換這樣問題的數據,因為這個時間是一個四位數的數字,如果要使用結束的年份,我們還要補齊前兩位的數字。

首先,我們需要找到問題一的數據,這樣我們才能將其更新。要保證其他的數據不被更新,因為其他的數據有可能是已經格式化好的,也有可能是我們下面要處理的。

我們要處理的時間范圍的數據,其中包含有“-”,這樣我們就可以通過這個特殊的字符串來過濾我們要處理的數據,然后,通過 split() 利用“-”將數據分割,將結果的第一部分作為處理的最終結果。

代碼如下

row_with_dashes = df['Date'].str.contains('-').fillna(False)for i, dash in df[row_with_dashes].iterrows():    df.at[i,'Date'] = dash['Date'][0:4]df['Date'].value_counts()

運行結果如下:

img

處理問題二

問題二的數據體現了數據本身的不准確性,是一個估計的年份時間,我們將其轉換為年份,那么,就只要保留最后四位數字即可,該數據的特點就是數據包含“c”,這樣我們就可以通過這一特征將需要轉換的數據過濾出來。

row_with_cs = df['Date'].str.contains('c').fillna(False)for i,row in df[row_with_cs].iterrows():    df.at[i,'Date'] = row['Date'][-4:]df[row_with_cs]

運行結果如下:

img

處理問題三四

將這問題三四的數據賦值成初始值 0

df['Date'] = df['Date'].replace('Unknown','0',regex=True)
df['Date'] = df['Date'].replace('n.d.','0',regex=True)
df['Date']

運行結果如下:

img

4、附:完成代碼

注意:完整代碼中刪除了數據展示部分

import pandas as pd
df = pd.read_csv('../data/Artworks.csv').head(100)
df.head(10)
df['Date'].value_counts()
row_with_dashes = df['Date'].str.contains('-').fillna(False)
for i, dash in df[row_with_dashes].iterrows():
    df.at[i,'Date'] = dash['Date'][0:4]
df['Date'].value_counts()
row_with_cs = df['Date'].str.contains('c').fillna(False)
for i,row in df[row_with_cs].iterrows():
    df.at[i,'Date'] = row['Date'][-4:]
df['Date'].value_counts()
df['Date'] = df['Date'].replace('Unknown','0',regex=True)
df['Date'] = df['Date'].replace('n.d.','0',regex=True)
df['Date'].value_counts()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM