Pandas 數(shù)據(jù)類(lèi)型操作
本文總結(jié)了 Pandas 中進(jìn)行數(shù)據(jù)類(lèi)型轉(zhuǎn)換的三種基本方法,同時(shí)介紹了基于數(shù)據(jù)類(lèi)型取數(shù)的方法:
使用 astype() 函數(shù)進(jìn)行強(qiáng)制類(lèi)型轉(zhuǎn)換 通過(guò)自定義函數(shù)來(lái)進(jìn)行數(shù)據(jù)類(lèi)型轉(zhuǎn)換 使用 Pandas 提供的函數(shù)如 to_numeric()、to_datetime() 等進(jìn)行轉(zhuǎn)化 select_dtypes 函數(shù)的使用
一、Pandas、Python、Numpy 各自支持的數(shù)據(jù)類(lèi)型
下表中展示的是 Pandas、Python 和 Numpy 中支持的數(shù)據(jù)類(lèi)型,可以看到 pandas中支持的類(lèi)型是最豐富的。

二、模擬數(shù)據(jù)
2.1 導(dǎo)入數(shù)據(jù)
下面是模擬的一份數(shù)據(jù),包含多個(gè)字段名稱(chēng)

import pandas as pd
import numpy as np
# 讀取數(shù)據(jù)
df = pd.read_csv("數(shù)據(jù)類(lèi)型操作.csv")
df

2.2 數(shù)據(jù)類(lèi)型查看
查看數(shù)據(jù)的字段類(lèi)型:

df.dtypes # 各字段的數(shù)據(jù)類(lèi)型
df.team.dtype # 某個(gè)字段的類(lèi)型
s.dtype # Series 的類(lèi)型
df.dtypes.value_counts() # 各類(lèi)型有多少個(gè)字段
三、實(shí)際案例
3.1 字符型轉(zhuǎn)成數(shù)值型
比如我們想在數(shù)據(jù)上進(jìn)行一些操作,比如將"2019年"、和"2020年"的數(shù)據(jù)相加:很明顯數(shù)據(jù)不是我們想要的結(jié)果。
根本原因:這兩個(gè)字段是字符類(lèi)型,進(jìn)行+操作,是直接將里面的內(nèi)容拼接在一起,而不是里面數(shù)值的相加。

正確的操作:
1、先把這兩個(gè)字段中的數(shù)字單獨(dú)提取出來(lái)
# 分割之后取出第1個(gè)元素
df["2020年_新"] = df["2020年"].apply(lambda x:x.split("元")[0])
df["2019年_新"] = df["2019年"].apply(lambda x:x.split("元")[0])
df

2、查看數(shù)據(jù)類(lèi)型
生成的兩個(gè)新字段仍然是字符類(lèi)型,不能直接相加

3、將數(shù)字表現(xiàn)型的字符型數(shù)據(jù)轉(zhuǎn)成數(shù)值型
有兩種方法實(shí)現(xiàn)這種需求:
pd.astype("float") :指定類(lèi)型 to_numeric():直接轉(zhuǎn)化
## 字符類(lèi)型的數(shù)值轉(zhuǎn)成純數(shù)值型
# 等價(jià)寫(xiě)法:df["2020年_新"] = df.astype({"2020年_新":"int") 字典形式傳入
df["2020年_新"] = df["2020年_新"].astype("int")
df['2019年_新'] = pd.to_numeric(df['2019年_新'], errors='coerce')
df

3、將兩個(gè)新的字段相加
df["前兩年之和"] = df["2020年_新"] + df["2019年_新"]
df

求兩個(gè)年份之間的差值:

3.2 數(shù)值型轉(zhuǎn)成字符型
求出 2020 年的增長(zhǎng)率:
df["增長(zhǎng)率"] = df["前兩年之差"] / df["2019年_新"]
df

現(xiàn)在整個(gè)增長(zhǎng)率是 float 的數(shù)值型,我們想把它轉(zhuǎn)成 % 的形式,也就是字符類(lèi)型的數(shù)據(jù):
顧客姓名 object
顧客編碼 int64
客戶(hù)部門(mén) object
客戶(hù)組別 float64
2019年 object
2020年 object
日 int64
月 int64
年 int64
是否大客戶(hù) object
2020年_新 int64
2019年_新 int64
前兩年之和 int64
前兩年之差 int64
增長(zhǎng)率 float64 # 數(shù)值型數(shù)據(jù)
dtype: object
在這里也是兩種方法滿(mǎn)足上面的需求:
方法1:通過(guò) str 函數(shù)的轉(zhuǎn)化 方法2:通過(guò) format 函數(shù)的格式化輸出
df["增長(zhǎng)率1"] = df["增長(zhǎng)率"].apply(lambda x: str(round(100*x,2)) + "%")
df["增長(zhǎng)率2"] = df["增長(zhǎng)率"].apply(lambda x: format(x,'.2%'))
df

顧客姓名 object
顧客編碼 int64
客戶(hù)部門(mén) object
客戶(hù)組別 float64
2019年 object
2020年 object
日 int64
月 int64
年 int64
是否大客戶(hù) object
2020年_新 int64
2019年_新 int64
前兩年之和 int64
前兩年之差 int64
增長(zhǎng)率 float64
增長(zhǎng)率1 object # 兩個(gè)字符類(lèi)型的數(shù)據(jù)
增長(zhǎng)率2 object
dtype: object
3.3 數(shù)值型數(shù)據(jù)存在缺失值
如果某個(gè)字段中大部分的數(shù)據(jù)都是數(shù)值型,但是存在少量的缺失值的情況,可以使用下面的方法進(jìn)行轉(zhuǎn)化:

df["客戶(hù)組別"] = pd.to_numeric(df['客戶(hù)組別'], errors='coerce').fillna(0) # 未知的組用0代替;0可以換成其他數(shù)值
df

3.4 數(shù)值型類(lèi)型轉(zhuǎn)成時(shí)間類(lèi)型
如果在實(shí)際數(shù)據(jù)中,我們遇到類(lèi)似年、月、日等時(shí)間的數(shù)據(jù),可以進(jìn)行轉(zhuǎn)化:比如我們想根據(jù)數(shù)據(jù)中的年月日生成一個(gè)生日的字段

1、上面的日、月、年現(xiàn)在是數(shù)值類(lèi)型的數(shù)據(jù),不能直接相加,先進(jìn)行轉(zhuǎn)化:
df["月"] = df["月"].astype(str)
df["年"] = df["年"].astype(str)
2、轉(zhuǎn)成字符型數(shù)據(jù)之后,再進(jìn)行相加:
df["生日"] = df["年"] + "-" + df["月"] + "-" + df["日"]
df

3、通過(guò) pd.to_datetime 轉(zhuǎn)成 pandas 中的時(shí)間類(lèi)型數(shù)據(jù)
df["生日"] = df["生日"].apply(lambda x: pd.to_datetime(x,format="%Y-%m-%d"))
df.dtypes

經(jīng)過(guò)檢驗(yàn):如果字段是用英文表示的,下面的方法可以直接轉(zhuǎn)成datetime64[ns]類(lèi)型,使用中文漢字當(dāng)做屬性名的時(shí)候,該方法不適用。
Pandas 中的 to_datetime() 函數(shù)可以把單獨(dú)的 year、month、day 三列合并成一個(gè)單獨(dú)的時(shí)間戳:
pd.to_datetime(df[['year', 'month', 'day']]) # 組合成日期


3.5 布爾值判斷使用
比如在是否為大客戶(hù)中,我們想將 Y 換成 True,N 換成 False,可以通過(guò) np.where 來(lái)是實(shí)現(xiàn):
df["是否大客戶(hù)"] = np.where(df["是否大客戶(hù)"] == "Y", True, False)
df

3.6 讀取文件直接轉(zhuǎn)換
在使用 pandas 讀取文件的時(shí)候,可以直接改變數(shù)據(jù)類(lèi)型,使用參數(shù)是 converters:
df0 = pd.read_csv("數(shù)據(jù)類(lèi)型操作.csv",
converters={
"顧客編碼":str, # 指定改變的函數(shù)
"2019年":lambda x:float(x.split("元")[0]), # 切割函數(shù)
"2020年":lambda x:float(x.replace("元","")), # 替換函數(shù)
"客戶(hù)組別":lambda x: pd.to_numeric(x, errors='coerce'),
"是否大客戶(hù)":lambda x:np.where(x == "Y",True,False)
}
)
df0

四、根據(jù)數(shù)據(jù)類(lèi)型取數(shù)
df 中的數(shù)據(jù)類(lèi)型為:object、int64、float64、bool、datetime64[ns]
df.dtypes
# 結(jié)果
顧客姓名 object
顧客編碼 int64
客戶(hù)部門(mén) object
客戶(hù)組別 float64
2019年 object
2020年 object
日 object
月 object
年 object
是否大客戶(hù) bool
2020年_新 int64
2019年_新 int64
前兩年之和 int64
前兩年之差 int64
增長(zhǎng)率 float64
增長(zhǎng)率1 object
增長(zhǎng)率2 object
生日 datetime64[ns]
dtype: object
4.1 包含數(shù)據(jù)類(lèi)型
df.select_dtypes(include=["object"]) # 包含object類(lèi)型的數(shù)據(jù)

也可以同時(shí)篩選包含多個(gè)數(shù)據(jù)類(lèi)型:
df.select_dtypes(include=["object","bool"])

4.2 不包含數(shù)據(jù)類(lèi)型
df.select_dtypes(exclude=["object"]) # 不包含object類(lèi)型的數(shù)據(jù)

同時(shí)排除多個(gè)字段數(shù)據(jù)類(lèi)型:
df.select_dtypes(exclude=["object","bool"]) # 兩個(gè)類(lèi)型的數(shù)據(jù)同時(shí)排除

五、總結(jié)
對(duì)數(shù)據(jù)進(jìn)行操作的第一步就是保證我們?cè)O(shè)置了正確的數(shù)據(jù)類(lèi)型,然后才能進(jìn)行后續(xù)的數(shù)據(jù)處理、數(shù)據(jù)分析、可視化等一系列的操作。不用的數(shù)據(jù)類(lèi)型可以用不同的處理方法。
注意,一個(gè)列只能有一個(gè)總數(shù)據(jù)類(lèi)型。本文中介紹了 Pandas 中常見(jiàn)的數(shù)據(jù)類(lèi)型轉(zhuǎn)化和基于數(shù)據(jù)類(lèi)型取數(shù)的方法,希望對(duì)讀者有所幫助。
