1. 程式人生 > 其它 >學習筆記Python之Pandas

學習筆記Python之Pandas

Pandas 資料結構—Series

Pandas Series 類似表格中的一個列(column),類似於一維陣列,可以儲存任何資料型別。

Series由索引(index)和列組成,函式如下:

pandas.Series(data,index,dtype,name,copy)

引數說明

  • data:一組資料(ndarray型別)
  • index:資料索引標籤,如果不指定,預設從0開始
  • dtype:資料型別,預設會自己判斷
  • name:設定名稱
  • copy:拷貝資料,預設為False

建立一個簡單的Series例項:

import pandas as pd
a = [1,2,3]
myvar = pd.Series(a)
print(myvar)

輸出結果如下:

從上圖可知,如果沒有指定索引,索引值就從0 開始,我們可以根據索引值讀取資料:

import pandas as pd
a = [1,2,3]
myvar = pd.Series(a)
print(myver[1])

輸出結果為:

2

我們可以指定索引值,如下例:

import pandas as pd
a = ["Google","Runoob",'Wiki']
myvar = pd.Series(a,index = ["x","y","z"])
print(myvar)

輸出結果如下:

根據索引值讀取資料:

import pandas as pd
a 
= ["Google","Runoob",'Wiki'] myvar = pd.Series(a,index = ["x","y","z"]) print(myvar["y"])

輸出結果如下:

Runoob

我們也可以使用key/value物件,類似字典來建立Series:

import pandas as pd
sites = {1:"Google", 2:"Runoob", 3:"Wiki"}
myvar = pd.Series(sites)
print(myvar)

輸出結果如下:

從上圖可知,字典的key變成了索引值。

如果我們只需要字典的中的一部分資料,只需要指定需要資料的索引即可,如下例項:

import pandas as pd
sites = {1:"Google", 2:"Runoob", 3:"Wiki"}
myvar = pd.Series(sites,index = [1,2])
print(myvar)

輸出結果如下:

設定Series名稱引數:

import pandas as pd
sites = {1:"Google", 2:"Runoob", 3:"Wiki"}
myvar = pd.Series(sites,index = [1,2],name = "RUNOOB-Series-TEST")
print(myvar)

輸出結果如下:

Pandas資料結構 - DataFrame

DataFrame 是一個表格型的資料結構,它含有一組有序的列,每列可以是不同的值型別(數值、字串、布林型值)。DataFrame既有行索引也有列索引,它可以被看作是由Series組成的字典(共同用一個索引)

DataFrame構造方法如下:

pandas.DataFrame(data,index,columns,dtype,copy)

引數說明:

  • data:一組資料(ndarray、series、map、lists、dict等型別)
  • index:索引值,或者可以稱為行標籤
  • columns:列標籤,預設為RangeIndex(0,1,2,...,n)
  • dtype:資料型別
  • copy:拷貝資料,預設為False

Pandas DataFrame 是一個二維的陣列結構,類似二維陣列

#使用列表建立
import pandas as pd
data = [["Google",10],[“Runoob”,12],["Wiki",13]]
df = pd.DataFrame(data,columns = ['Site','Age'],dtype = float)
print(df)

輸出結果如下:

以下例項用ndarrays 建立,ndarray 的長度必須相同,如果傳遞了index,則索引的長度應等於陣列的長度,如果沒有傳遞索引,則預設情況下,索引將是range(n),其中n是陣列長度。

#使用ndarrays建立
import pandas as pd
data = {'Site':['Google','Runoob','Wiki'],'Age':[10,12,13]}

#這裡陣列指的是['Google','Runoob','Wiki'],[10,12,13]
df = pd.DataFrame(data) 

print(df)

輸出結果如下:

由以上輸出結果可知,DataFrame資料型別一個表格,包括rows(行),和columns(列)

還可以使用字典(key/value),其中字典的key為列名:

#使用字典建立
import pandas as pd
data = [{'a':1, 'b':2},{'a':5, 'b':10, 'c':20}]
df = pd.DataFrame(data)
print(df)

輸出結果為

沒有對應的部分資料為NaN

Pandas可以使用loc屬性返回指定行的資料,如果沒有設定索引,第一行索引為0,第二行索引為1,以此類推:

import pandas as pd

data = {
  "calories": [420, 380, 390],
  "duration": [50, 40, 45]
}

# 資料載入到 DataFrame 物件
df = pd.DataFrame(data)

# 返回第一行
print(df.loc[0])
# 返回第二行
print(df.loc[1])

輸出結果如下:注意:返回結果其實就是一個Pandas Series資料。

#也可以返回多行資料,使用[[...]]格式,...為各行索引
import
pandas as pd data = { "calories": [420, 380, 390], "duration": [50, 40, 45] } # 資料載入到 DataFrame 物件 df = pd.DataFrame(data) # 返回第一行和第二行 print(df.loc[[0, 1]])

輸出結果為:注意:返回結果其實就是一個Pandas DataFrame 資料

#我們可以指定索引值,如下例項:
import pandas as pd
data = {
    "calories":[420,380,390],
    "duration":[50,40,45]
}

df = pd.DataFrame(data, index = ["day1","day2","day3"])

print(df)

輸出結果為:

Pandas可以使用loc屬性返回指定索引對應到某一行:

import pandas as pd
data = {
    "calories":[420,380,390],
    "duration":[50,40,45]
}

df = pd.DataFrame(data, index = ["day1","day2","day3"])

#指定索引
print(df.loc["day2"])

輸出結果為:

Pandas CSV檔案

CSV(Comma-Separated Values,逗號分隔值,有時也稱為字元分隔值,因為分隔字元也可以不是逗號),其檔案以純文字形式儲存表格資料(數字和文字)

CSV是一種通用的、相對簡單的檔案格式,被使用者、商業和科學廣泛應用。

Pandas可以很方便的處理CSV檔案。

import pandas as pd

df = pd.read_csv("nba.csv")

print(df.to_string())

to_string() 用於返回DataFrame型別的資料,如果不使用該函式,則輸出結果為資料的前面5行和末尾5行,中間部分以...代替。使用了to_string相當於全部輸出

import pandas as pd

df = pd.read_csv('nba.csv')

print(df)

輸出結果為:

我們也可以使用to_csv()方法將DataFrame儲存為csv檔案:

import pandas as pd

#三個欄位 name,site,age
nme = ["Google","Runoob","Taobao","Wiki"]
st = ["www.google.com","www.runoob.com","www.taobao.com","www.wikipedia.org"]
ag = [90,40,80,98]

#字典
dict = {'name':nme,'site':st,'age':ag}

df = pd.DataFrame(dict)

#儲存 dataframe
df.to_csv('site.csv')

執行成功後,我們開啟site.csv檔案,顯示結果如下:

資料處理

1.head()

head(n)方法用於讀取前面的n行,如果不填引數n,預設返回5行。

import pandas as pd

df = pd.read_csv("nba.csv")

print(df.head())

輸出結果為:

2.tail()

tail(n)方法用於讀取尾部的n行,如果不填引數n,預設返回5行,空行各個欄位的值返回NaN

import pandas as pd

df = pd.read_csv("nba.csv")

print(df.tail())

輸出結果為:

3.info()

info()方法返回表格的一些基本資訊:

import pandas as pd

df = pd.read_csv("nba.csv")

print(df.info())

輸出結果為:

non-null為非空資料,我們可以看到上面的資訊中,總共458行,College欄位的空值最多。


Pandas 資料清洗

資料清洗是對一些沒有用的資料進行處理的過程。

很多資料集存在資料缺失、資料格式錯誤、錯誤資料或重複資料的情況,如果要對使資料分析更加準確,就需要對這些沒有用的資料進行處理。

本文使用到的測試資料如下:

上表包含了四種空資料:

  • n/a
  • NA
  • na

1 Pandas清洗空值

如果我們要刪除包含空欄位的行,可以使用dropna()方法,語法格式如下:

DataFrame.dropna(sxis = 0,how = 'any',thresh = None,subset = None,inplace = False)

引數說明:

  • axis:預設為0,表示逢空值剔除整行,如果設定引數 axis = 1表示逢空值去掉整列
  • how:預設為'any'如果一行(或一列)裡任何一個數據有出現NA就去掉整行,如何設定how = 'all'一行(或列)都是NA才去掉這整行
  • thresh:設定需要多少非空值的資料才可以保留下來的。
  • subset:設定想要檢查的列。如果是多個列,可以使用列名的list作為引數
  • inplace:如果設定True,將計算得到的值直接覆蓋之前的值並返回None,修改的是源資料。

我們可以通過isnull()判斷各個單元格是否為空。

import pandas as pd

df = read_csv("property-data.csv")

print(df['NUM_BEDROOMS'])
print(df['NUM_BEDROOMS']).isnull()

以上例項輸出結果如下:

以上例子中我們看到Pandas把n/a和NA當作空資料,而認為na不是空資料,不符合我們要求,我們可以指定空資料型別:

import pandas as pd

missing_values = ["n/a", "na", "--"]
df = read_csv("property-data.csv", na_values = missing_values)

print(df['NUM_BEDROOMS'])
print(df['NUM_BEDROOMS']).isnull()

以上例項輸出結果如下:

接下來的例項演示了刪除包含空資料的行。

import pandas as pd

df = pd.read_csv("property-data.csv")

new_df = df.dropna()

print(new_df.to_string())

以上例項輸出結果如下:

注意:預設情況下,dropna()方法返回一個新的DataFrame,不會修改源資料。

如果你要修改源資料DataFrame,可以使用inplace = True 引數:

import pandas as pd

df = pd.read_csv('property-data.csv')

df.dropna(inplace = True)

print(df.to_string())

以上例項輸出結果如下:

我們也可以移除指定列有空值的行:

import pandas as pd

df = pd.read_csv("property-data.csv")

df.dropna(subset = ['ST_NUM'],inplace = True)

print(df.to_string())

以上例項輸出結果如下:

我們也可以用fillna()方法來替換一些空欄位:

import pandas as pd

df = pd.read_csv("property-data.csv")

df.fillna(12345,inplace = True)

print(df.to_string())

以上例項輸出結果如下:

我們也可以指定某一個列來替換資料:

import pandas as pd

df = pd.read_csv('property-data.csv')

df['PID'].fillna(12345, inplace = True)#指定替換PID列的空資料

print(df.to_string())

以上例項輸出結果如下:

替換空單元格的常用方法是計算列的均值、中位數值或眾數。

Pandas使用mean()、median()和mode()方法計算列的均值(所有值加起來的平均值)、中位數值(排序後排在中間的數)和眾數(出現頻率最高的數)。

#使用mean()方法計算列的均值並替換空單元格
import pandas as pd

df = pd.read_csv("property-data.csv")

x = df["ST_NUM"].mean()   #同理可以換成中位數median()、眾數mode()

df["ST_NUM"].fillna(x,inplace = True)

print(df.to_string())

以上例項輸出結果如下,紅框為計算的均值替換來空單元格:

2 Pandas清洗格式錯誤資料

資料格式錯誤的單元格會使資料分析變得困難,我們可以通過包含空單元格的行,或者將列中的所有單元格轉換為相同格式的資料

以下例項會格式化日期:

import pandas as pd

#第三個日期格式錯誤
data = {
    "Date":['2020/12/01', '2020/12/02', '20201226']
    "duration":[50, 40, 45]
}
df = pd.DataFrame(data, index = ["day1","day2","day3"])

df["Date"] = pd.to_datetime(df["Date"])

print(df.to_string())

以上例項輸出結果如下:

資料錯誤也是很常見的情況,我們可以對錯誤的資料進行替換或者移除。

以下例項會替換錯誤年齡的資料:

import pandas as pd

person = {
    "name":['Google','Runoob','Taobao'],
    "age":[50,40,12345] #這裡12345 年齡資料是錯誤的
}
df = pd.DataFrame(person)

df.loc[2,'age'] = 30 #修改資料

print(df.to_string())

以上例項輸出結果如下:

也可以設定條件語句:

#將age大於120的設定為120
import pandas as pd

person = {
    "name":['Google','Runoob','Taobao'],
    "age":[50,200,12345] 
}
df = pd.DataFrame(person)

for x in df.index:
        if df.loc[x,"age"]>120:
                df.loc[x,"age"] = 120

print(df.to_string())

以上例項輸出結果如下:

也可以將錯誤的資料的行刪除:

#將age大於120的設定為刪除
import pandas as pd

person = {
    "name":['Google','Runoob','Taobao'],
    "age":[50,40,12345] 
}
df = pd.DataFrame(person)

for x in df.index:
        if df.loc[x,"age"]>120:
                df.drop(x,inplace =True)

print(df.to_string())

以上例項輸出結果如下:

3 Pandas 清洗重複資料

如果我們要清洗重複資料,可以使用duplicated()和drop_dulicates()方法。

如果對應的資料是重複的,dulicated()會返回True,否則返回False

import pandas as pd

person = {
  "name": ['Google', 'Runoob', 'Runoob', 'Taobao'],
  "age": [50, 40, 40, 23]  

df = pd.DataFrame(person)

print(df.duplicated())

以上例項輸出結果如下:

刪除重複資料,可以直接使用drop_dulicates()方法。

import pandas as pd

person = {
  "name": ['Google', 'Runoob', 'Runoob', 'Taobao'],
  "age": [50, 40, 40, 23]  

df = pd.DataFrame(person)

df.drop_duplicates(inplace = True)

print(df)

以上例項輸出結果如下: