數據處理
數據加載
首先,我們需要將收集的數據加載到內存中,才能進行進一步的操作。pandas提供了非常多的讀取數據的函數,分別應用在各種數據源環境中,我們常用的函數爲:
- read_csv
- read_table
- read_sql
說明:
- read_csv與read_table默認使用的分隔符不同。
常用參數
read_csv與read_table常用的參數:
- sep / delimiter
- header
- names
- index_col
- usecols
導入頭文件
import numpy as np
import pandas as pd
讀取csv文件*
# 讀取參數指定路徑的文件(數據集),返回讀取後的結果。(DataFrame類型)
# header 用來指定標題行,如果數據集中沒有標題行,則指定爲None。
# sep指定數據之間的分隔符,默認爲逗號(,)。
# df = pd.read_csv("spider.csv", header=None)
# 在讀取數據的時候,可以通過names屬性設置列索引。
# df = pd.read_csv("spider.csv", header=None, names=["日期", "鏈接", "內容", "票房", "票房2"])
# 可以將數據集中的某一列(某幾列)設置爲行索引。通過index_col來進行指定。
# df = pd.read_csv("spider.csv", header=None, names=["日期", "鏈接", "內容", "票房", "票房2"], index_col="日期")
# 通過通過usecols參數來設置需要使用的列。
df = pd.read_csv("spider.csv", header=None, names=["日期", "鏈接", "內容", "票房", "票房2"], usecols=["日期", "鏈接"])
df.head()
讀取並執行sql
# read_table與read_csv功能一樣,只是read_table默認的分隔符爲\t (製表符),而
# read_csv默認的分隔符爲逗號(,)
df = pd.read_table("spider.csv", sep=",", header=None)
df
# read_sql從數據庫中讀取數據集。
import sqlite3
連接數據庫
con = sqlite3.connect("test.db")
建表
con.execute("create table person(id int primary key, name varchar)")
插入表
# con.execute("insert into person(id, name) values (3, '3dsfdsa')")
con.execute("insert into person(id, name) values (4, null)")
con.commit()
查詢數據
df = pd.read_sql("select id, name from person", con)
數據持久化
寫入文件
DataFrame與Series對象的to_csv方法,可以將數據寫入文件或者指定的數據流中。
- to_csv
常用參數
- sep
- header 是否寫入標題行
- na_rep 空值的表示
- index 是否寫入索引
- index_label 索引字段的名稱
- columns 寫入的字段
# 向文件中寫入數據。
# df.to_csv("c:/test.csv")
# 通過sep參數指定分隔符。
# df.to_csv("c:/test.csv", sep="。")
# header,用來設置是否寫入標題行,默認爲True。
# df.to_csv("c:/test.csv", header=False)
# 參數na_rep來設置空值的顯示方式,默認空值不顯示。
# df.to_csv("c:/test.csv", header=False, na_rep="空值")
# index 設置是否寫入索引。默認爲True。
# df.to_csv("c:/test.csv", header=False, index=False)
# index_label用來設置索引字段的名稱,默認爲""(空字符串)
# df.to_csv("c:/test.csv", index_label="索引字段名稱")
# columns參數控制需要寫入哪些列。
# df.to_csv("c:/test.csv", columns=["name"])
# 將DataFrame數據寫入文件(類文件)對象中。
from io import StringIO
s = StringIO()
df.to_csv(s)
# 將指針移動到文件的靠頭。因爲我們之前剛剛寫入過內容,如果不移動到開頭,
# 將無法使用read讀取。
s.seek(0)
s.read()
# s.getvalue()
數據清洗
我們需要對數據進行一些預處理操作,才能用到後續的數據分析與機器學習中。這是因爲,無論數據的來源爲何處,我們都不可能保證數據一定是準確無誤的。
數據清洗可以包含以下幾方面內容:
- 處理缺失值
- 處理異常值
- 處理重複值
缺失值處理
發現缺失值
Pandas中,會將float類型的nan與None視爲缺失值,我們可以通過如下方法來檢測缺失值:
- info
- isnull
- notnull
說明:
- 判斷是否存在空值,可以將isnull與any或all結合使用。
丟棄缺失值
對於缺失值,我們可以將其進行丟棄處理(dropna)。
說明:
- how:指定dropna丟棄缺失值的行爲,默認爲any。
- axis:指定丟棄行或者丟棄列(默認爲丟棄行)。
- thresh:當非空數值達到該值時,保留數據,否則刪除。
- inplace:指定是否就地修改,默認爲False。
填充缺失值
我們也可以對缺失值進行填充(fillna)。
說明:
- value:填充所使用的值。可以是一個字典,這樣就可以爲DataFrame的不同列指定不同的填充值。
- method:指定前值(上一個有效值)填充(pad / ffill),還是後值(下一個有效值)填充(backfill / bfill)。
- limit:如果指定method,表示最大連續NaN的填充數量,如果沒有指定method,則表示最大的NaN填充數量。
- inplace:指定是否就地修改,默認爲False。
無效值處理
檢測無效值
可以通過DataFrame對象的describe方法查看數據的統計信息。不同類型的列,統計信息也不太相同。
重複值處理
在處理數據中,可能會出現重複的數據,我們通常需要將重複的記錄刪除。
發現重複值
我們可以通過duplicated方法來發現重複值。該方法返回Series類型的對象,值爲布爾類型,表示是否與上一行重複。
參數說明:
- subset:指定依據哪些列判斷是否重複,默認爲所有列。
- keep:指定記錄被標記爲重複(True)的規則。默認爲first。
刪除重複值
通過drop_duplicates可以刪除重複值。
參數說明:
- subset:指定依據哪些列判斷是否重複,默認爲所有列。
- keep:指定記錄刪除(或保留)的規則。默認爲First。
- inplace:指定是否就地修改,默認爲False。
數據過濾
可以使用布爾數組或者索引數組的方式來過濾數據。
另外,也可以用DataFrame類的query方法來進行數據過濾。在query方法中也可以使用外面定義的變量,需要在變量前加上@。
數據轉換
應用與映射
Series與DataFrame對象可以進行行(列)或元素級別的映射轉換操作。對於Series,可以調用apply或map方法。對於DataFrame,可以調用apply或applymap方法。
- apply:通過函數實現映射轉換。【Series傳遞元素,DataFrame傳遞行或列。】
- map:對當前Series的值進行映射轉換。參數可以是一個Series,一個字典或者是一個函數。
- applymap:通過函數實現元素級的映射轉換。
替換
Series或DataFrame可以通過replace方法可以實現元素值的替換操作。
- to_replace:被替換值,支持單一值,列表,字典,正則表達式。
- regex:是否使用正則表達式,默認爲False。
數據合併
concat
我們可以通過DataFrame或Series類型的concat方法,來進行連接操作,連接時,會根據索引進行對齊。
- axis:指定連接軸,默認爲0。
- join:指定連接方式,默認爲外連接。【outer:並集,inner:交集】
- keys:可以用來區分不同的數據組。
- join_axes:指定連接結果集中保留的索引。
- ignore_index:忽略原來連接的索引,創建新的整數序列索引,默認爲False。
append
在對行進行連接時,也可以使用Series或DataFrame的append方法。
# DataFrame的合併,是根據索引對齊的。縱向合併根據列索引對齊,橫向合併會根據行索引對齊。
h = df.head()
t = df.tail()
t.columns = ["date", "link", "info", "v1", "v2"]
# display(h, t)
# t.cloumns[0] = "date"
# 縱向合併
# pd.concat([h, t], axis=0)
# 橫向合併
# t.index = [0, 1, 2, 3, 4]
# pd.concat([h, t], axis=1)
# 可以通過join來指定對齊方式。outer(默認)爲並集,inner爲交集。
# pd.concat([h, t], axis=0, join="outer")
# pd.concat([h, t], axis=0, join="inner")
# pd.concat([h, t], axis=0, keys=["head", "tail"])
# join_axes 指定結果集中保留的索引。
# pd.concat([h, t], axis=0, join_axes=[h.columns])
# pd.concat([h, t], axis=0, join_axes=[t.columns])
# 忽略以前的索引,對索引進行重排。
pd.concat([h, t], ignore_index=True)
merge
通過pandas或DataFrame的merge方法,可以進行兩個DataFrame的連接,這種連接類似於SQL中對兩張表進行的join連接。
- how:指定連接方式。可以是inner, outer, left, right,默認爲inner。
- on 指定連接使用的列(該列必須同時出現在兩個DataFrame中),默認使用兩個DataFrame中的所有同名列進行連接。
- left_on / right_on:指定左右DataFrame中連接所使用的列。
- left_index / right_index:是否將左邊(右邊)DataFrame中的索引作爲連接列,默認爲False。
- suffixes:當兩個DataFrame列名相同時,指定每個列名的後綴(用來區分),默認爲_x與_y。
df1 = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
df2 = pd.DataFrame([[4, 2, 3], [10, 8, 9], [7, 8, 10]], columns=[4, 1, 2])
display(df1, df2)
# 沒有指定連接條件,則使用所用同名字段進行等值連接(相當於是數據庫中的自然連接natural join。)
# df1.merge(df2)
# 我們可以通過how指定連接方式。默認是inner。
# inner:內連接 outer:全外連接 left:左外連接 right:右外連接
# df1.merge(df2, how="outer")
# df1.merge(df2, how="left")
# df1.merge(df2, how="right")
# 我們可以通過on來指定連接字段(列),該列必須同時出現在兩個DataFrame中。如果沒有指定on,
# 則使用兩個DataFrame中的所有同名字段進行等值連接。
# df1.merge(df2, on=1)
# 我們可以使用left_on與right_on分別指定左表與右表用於連接的列名。
# df1.merge(df2, left_on=0, right_on=4)
# 可以指定left_index與right_index來設置是否使用索引列進行連接。
# df1.merge(df2, left_index=True, right_index=True)
# 也可以指定一張表使用索引,一張表使用列來進行連接。
# df1.merge(df2, left_index=True, right_on=1)
# left_on與left_index(True)或者right_on與right_index(True)不能可以共存
# 錯誤。
# df1.merge(left_on=0, left_index=True, right_index=True)
# 可以通過suffixes參數來指定,當列名重名時,每個表列名的後綴,默認是_x與_y。
df1.merge(df2, left_on=0, right_on=4, suffixes=["_A", "_B"])
join
與merge方法類似,但是默認使用索引進行連接。
- how:指定連接方式。可以是inner, outer, left, right,默認爲left。
- on:設置當前DataFrame對象使用哪個列與參數對象的索引進行連接。
- lsuffix / rsuffix:當兩個DataFrame列名相同時,指定每個列名的後綴(用來區分),如果不指定,列名相同會產生錯誤。