Pandas基本功能詳解 | 輕鬆玩轉Pandas(2)

教你學會 Pandas 不是個人目的,教你輕鬆玩轉 Pandas 纔是個人目的。我會經過一系列實例來帶入 Pandas 的知識點,讓你在學習 Pandas 的路上再也不枯燥。html

聲明:我所寫的輕鬆玩轉 Pandas 教程都是免費的,若是對你有幫助,你能夠持續關注我。python

Pandas數據結構詳解 | 輕鬆玩轉Pandas(1) 介紹了 Pandas 中經常使用的兩種數據結構 Series 以及 DataFrame,這裏來看下這些數據結構都有哪些經常使用的功能。數據結構

# 導入相關庫
import numpy as np
import pandas as pd
複製代碼

經常使用的基本功能

當咱們構建好了 Series 和 DataFrame 以後,咱們會常用哪些功能呢?來跟我看看吧。引用上一章節中的場景,咱們有一些用戶的的信息,並將它們存儲到了 DataFrame 中。app

由於大多數狀況下 DataFrame 比 Series 更爲經常使用,因此這裏以 DataFrame 舉例說明,但實際上不少經常使用功能對於 Series 也適用。函數

index = pd.Index(data=["Tom", "Bob", "Mary", "James"], name="name")

data = {
    "age": [18, 30, 25, 40],
    "city": ["BeiJing", "ShangHai", "GuangZhou", "ShenZhen"],
    "sex": ["male", "male", "female", "male"]
}

user_info = pd.DataFrame(data=data, index=index)
user_info
複製代碼
age city sex
name
Tom 18 BeiJing male
Bob 30 ShangHai male
Mary 25 GuangZhou female
James 40 ShenZhen male

通常拿到數據,咱們第一步須要作的是瞭解下數據的總體狀況,可使用 info 方法來查看。學習

user_info.info()
複製代碼
Index: 4 entries, Tom to James
Data columns (total 3 columns):
age     4 non-null int64
city    4 non-null object
sex     4 non-null object
dtypes: int64(1), object(2)
memory usage: 128.0+ bytes
複製代碼

若是咱們的數據量很是大,我想看看數據長啥樣,我固然不但願查看全部的數據了,這時候咱們能夠採用只看頭部的 n 條或者尾部的 n 條。查看頭部的 n 條數據可使用 head 方法,查看尾部的 n 條數據可使用 tail 方法。人工智能

user_info.head(2)
複製代碼
age city sex
name
Tom 18 BeiJing male
Bob 30 ShangHai male

此外,Pandas 中的數據結構都有 ndarray 中的經常使用方法和屬性,如經過 .shape 獲取數據的形狀,經過 .T 獲取數據的轉置。spa

user_info.shape
複製代碼
(4, 3)
複製代碼
user_info.T
複製代碼
name Tom Bob Mary James
age 18 30 25 40
city BeiJing ShangHai GuangZhou ShenZhen
sex male male female male

若是咱們想要經過 DataFrame 來獲取它包含的原有數據,能夠經過 .values 來獲取,獲取後的數據類型實際上是一個 ndarray。設計

user_info.values
複製代碼
array([[18, 'BeiJing', 'male'],
       [30, 'ShangHai', 'male'],
       [25, 'GuangZhou', 'female'],
       [40, 'ShenZhen', 'male']], dtype=object)
複製代碼

描述與統計

有時候咱們獲取到數據以後,想要查看下數據的簡單統計指標(最大值、最小值、平均值、中位數等),好比想要查看年齡的最大值,如何實現呢?code

直接對 age 這一列調用 max方法便可。

user_info.age.max()
複製代碼
40
複製代碼

相似的,經過調用 minmeanquantilesum 方法能夠實現最小值、平均值、中位數以及求和。能夠看到,對一個 Series 調用 這幾個方法以後,返回的都只是一個聚合結果。

來介紹個有意思的方法:cumsum,看名字就發現它和 sum 方法有關係,事實上確實如此,cumsum 也是用來求和的,不過它是用來累加求和的,也就是說它獲得的結果與原始的 SeriesDataFrame 大小相同。

user_info.age.cumsum()
複製代碼
name
Tom       18
Bob       48
Mary      73
James    113
Name: age, dtype: int64
複製代碼

能夠看到,cummax 最後的結果就是將上一次求和的結果與原始當前值求和做爲當前值。這話聽起來有點繞。舉個例子,上面的 73 = 48 + 25cumsum 也能夠用來操做字符串類型的對象。

user_info.sex.cumsum()
複製代碼
name
Tom                    male
Bob                malemale
Mary         malemalefemale
James    malemalefemalemale
Name: sex, dtype: object
複製代碼

若是想要獲取更多的統計方法,能夠參見官方連接:Descriptive statistics

雖說常見的各類統計值都有對應的方法,若是我想要獲得多個指標的話,就須要調用屢次方法,是否是顯得有點麻煩呢?

Pandas 設計者天然也考慮到了這個問題,想要一次性獲取多個統計指標,只需調用 describe 方法便可

user_info.describe()
複製代碼
age
count 4.000000
mean 28.250000
std 9.251126
min 18.000000
25% 23.250000
50% 27.500000
75% 32.500000
max 40.000000

能夠看到,直接調用 describe 方法後,會顯示出數字類型的列的一些統計指標,如 總數、平均數、標準差、最小值、最大值、25%/50%/75% 分位數。若是想要查看非數字類型的列的統計指標,能夠設置 include=["object"] 來得到。

user_info.describe(include=["object"])
複製代碼
city sex
count 4 4
unique 4 2
top BeiJing male
freq 1 3

上面的結果展現了非數字類型的列的一些統計指標:總數,去重後的個數、最多見的值、最多見的值的頻數。

此外,若是我想要統計下某列中每一個值出現的次數,如何快速實現呢?調用 value_counts 方法快速獲取 Series 中每一個值出現的次數。

user_info.sex.value_counts()
複製代碼
male      3
female    1
Name: sex, dtype: int64
複製代碼

若是想要獲取某列最大值或最小值對應的索引,可使用 idxmaxidxmin 方法完成。

user_info.age.idxmax()
複製代碼
'James'
複製代碼

離散化

有時候,咱們會碰到這樣的需求,想要將年齡進行離散化(分桶),直白來講就是將年齡分紅幾個區間,這裏咱們想要將年齡分紅 3 個區間段。就可使用 Pandas 的 cut 方法來完成。

pd.cut(user_info.age, 3)
複製代碼
name
Tom      (17.978, 25.333]
Bob      (25.333, 32.667]
Mary     (17.978, 25.333]
James      (32.667, 40.0]
Name: age, dtype: category
Categories (3, interval[float64]): [(17.978, 25.333] < (25.333, 32.667] < (32.667, 40.0]]
複製代碼

能夠看到, cut 自動生成了等距的離散區間,若是本身想定義也是沒問題的。

pd.cut(user_info.age, [1, 18, 30, 50])
複製代碼
name
Tom       (1, 18]
Bob      (18, 30]
Mary     (18, 30]
James    (30, 50]
Name: age, dtype: category
Categories (3, interval[int64]): [(1, 18] < (18, 30] < (30, 50]]
複製代碼

有時候離散化以後,想要給每一個區間起個名字,能夠指定 labels 參數。

pd.cut(user_info.age, [1, 18, 30, 50], labels=["childhood", "youth", "middle"])
複製代碼
name
Tom      childhood
Bob          youth
Mary         youth
James       middle
Name: age, dtype: category
Categories (3, object): [childhood < youth < middle]
複製代碼

除了可使用 cut 進行離散化以外,qcut 也能夠實現離散化。cut 是根據每一個值的大小來進行離散化的,qcut 是根據每一個值出現的次數來進行離散化的。

pd.qcut(user_info.age, 3)
複製代碼
name
Tom      (17.999, 25.0]
Bob        (25.0, 30.0]
Mary     (17.999, 25.0]
James      (30.0, 40.0]
Name: age, dtype: category
Categories (3, interval[float64]): [(17.999, 25.0] < (25.0, 30.0] < (30.0, 40.0]]
複製代碼

排序功能

在進行數據分析時,少不了進行數據排序。Pandas 支持兩種排序方式:按軸(索引或列)排序和按實際值排序。

先來看下按索引排序:sort_index 方法默認是按照索引進行正序排的。

user_info.sort_index()
複製代碼
age city sex
name
Bob 30 ShangHai male
James 40 ShenZhen male
Mary 25 GuangZhou female
Tom 18 BeiJing male

若是想要按照列進行倒序排,能夠設置參數 axis=1ascending=False

user_info.sort_index(axis=1, ascending=False)
複製代碼
sex city age
name
Tom male BeiJing 18
Bob male ShangHai 30
Mary female GuangZhou 25
James male ShenZhen 40

若是想要實現按照實際值來排序,例如想要按照年齡排序,如何實現呢?

使用 sort_values 方法,設置參數 by="age" 便可。

user_info.sort_values(by="age")
複製代碼
age city sex
name
Tom 18 BeiJing male
Mary 25 GuangZhou female
Bob 30 ShangHai male
James 40 ShenZhen male

有時候咱們可能須要按照多個值來排序,例如:按照年齡和城市來一塊兒排序,能夠設置參數 by 爲一個 list 便可。

注意:list 中每一個元素的順序會影響排序優先級的

user_info.sort_values(by=["age", "city"])
複製代碼
age city sex
name
Tom 18 BeiJing male
Mary 25 GuangZhou female
Bob 30 ShangHai male
James 40 ShenZhen male

通常在排序後,咱們可能須要獲取最大的n個值或最小值的n個值,咱們可使用 nlargestnsmallest 方法來完成,這比先進行排序,再使用 head(n) 方法快得多。

user_info.age.nlargest(2)
複製代碼
name
James    40
Bob      30
Name: age, dtype: int64
複製代碼

函數應用

雖然說 Pandas 爲咱們提供了很是豐富的函數,有時候咱們可能須要本身定製一些函數,並將它應用到 DataFrame 或 Series。經常使用到的函數有:mapapplyapplymap

map 是 Series 中特有的方法,經過它能夠對 Series 中的每一個元素實現轉換。

若是我想經過年齡判斷用戶是否屬於中年人(30歲以上爲中年),經過 map 能夠輕鬆搞定它。

# 接收一個 lambda 函數
user_info.age.map(lambda x: "yes" if x >= 30 else "no")
複製代碼
name
Tom       no
Bob      yes
Mary      no
James    yes
Name: age, dtype: object
複製代碼

又好比,我想要經過城市來判斷是南方仍是北方,我能夠這樣操做。

city_map = {
    "BeiJing": "north",
    "ShangHai": "south",
    "GuangZhou": "south",
    "ShenZhen": "south"
}

# 傳入一個 map
user_info.city.map(city_map)
複製代碼
name
Tom      north
Bob      south
Mary     south
James    south
Name: city, dtype: object
複製代碼

apply 方法既支持 Series,也支持 DataFrame,在對 Series 操做時會做用到每一個值上,在對 DataFrame 操做時會做用到全部行或全部列(經過 axis 參數控制)。

# 對 Series 來講,apply 方法 與 map 方法區別不大。
user_info.age.apply(lambda x: "yes" if x >= 30 else "no")
複製代碼
name
Tom       no
Bob      yes
Mary      no
James    yes
Name: age, dtype: object
複製代碼
# 對 DataFrame 來講,apply 方法的做用對象是一行或一列數據(一個Series)
user_info.apply(lambda x: x.max(), axis=0)
複製代碼
age           40
city    ShenZhen
sex         male
dtype: object
複製代碼

applymap 方法針對於 DataFrame,它做用於 DataFrame 中的每一個元素,它對 DataFrame 的效果相似於 apply 對 Series 的效果。

user_info.applymap(lambda x: str(x).lower())
複製代碼
age city sex
name
Tom 18 beijing male
Bob 30 shanghai male
Mary 25 guangzhou female
James 40 shenzhen male

修改列/索引名稱

在使用 DataFrame 的過程當中,常常會遇到修改列名,索引名等狀況。使用 rename 輕鬆能夠實現。

修改列名只須要設置參數 columns 便可。

user_info.rename(columns={"age": "Age", "city": "City", "sex": "Sex"})
複製代碼
Age City Sex
name
Tom 18 BeiJing male
Bob 30 ShangHai male
Mary 25 GuangZhou female
James 40 ShenZhen male

相似的,修改索引名只須要設置參數 index 便可。

user_info.rename(index={"Tom": "tom", "Bob": "bob"})
複製代碼
age city sex
name
tom 18 BeiJing male
bob 30 ShangHai male
Mary 25 GuangZhou female
James 40 ShenZhen male

類型操做

若是想要獲取每種類型的列數的話,可使用 get_dtype_counts 方法。

user_info.get_dtype_counts()
複製代碼
int64     1
object    2
dtype: int64
複製代碼

若是想要轉換數據類型的話,能夠經過 astype 來完成。

user_info["age"].astype(float)
複製代碼
name
Tom      18.0
Bob      30.0
Mary     25.0
James    40.0
Name: age, dtype: float64
複製代碼

有時候會涉及到將 object 類型轉爲其餘類型,常見的有轉爲數字、日期、時間差,Pandas 中分別對應 to_numericto_datetimeto_timedelta 方法。

這裏給這些用戶都添加一些關於身高的信息。

user_info["height"] = ["178", "168", "178", "180cm"]
user_info
複製代碼
age city sex height
name
Tom 18 BeiJing male 178
Bob 30 ShangHai male 168
Mary 25 GuangZhou female 178
James 40 ShenZhen male 180cm

如今將身高這一列轉爲數字,很明顯,180cm 並不是數字,爲了強制轉換,咱們能夠傳入 errors 參數,這個參數的做用是當強轉失敗時的處理方式。

默認狀況下,errors='raise',這意味着強轉失敗後直接拋出異常,設置 errors='coerce' 能夠在強轉失敗時將有問題的元素賦值爲 pd.NaT(對於datetime和timedelta)或 np.nan(數字)。設置 errors='ignore' 能夠在強轉失敗時返回原有的數據。

pd.to_numeric(user_info.height, errors="coerce")
複製代碼
name
Tom      178.0
Bob      168.0
Mary     178.0
James      NaN
Name: height, dtype: float64
複製代碼
pd.to_numeric(user_info.height, errors="ignore")
複製代碼
name
Tom        178
Bob        168
Mary       178
James    180cm
Name: height, dtype: object
複製代碼

想要學習更多關於人工智能的知識,請關注公衆號:AI派

qrcode_for_gh_60cef389e81c_258.jpg

這裏我將整篇文章的內容整理成了pdf,想要pdf文件的能夠在公衆號後臺回覆關鍵字:pandas02

更多Pandas知識見:輕鬆玩轉Pandas

相關文章
相關標籤/搜索