Pandas數(shù)據(jù)類型操作

7_Pandas數(shù)據(jù)類型操作

數(shù)據(jù)處理、分析等操作的首要操作是我們正確地設(shè)置了數(shù)據(jù)類型,筆者自己經(jīng)常也會(huì)遇到數(shù)據(jù)類型不合理,而造成無(wú)法進(jìn)行后續(xù)操作的困境。本文總結(jié)了Pandas中進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換的三種基本方法,同時(shí)介紹了基于數(shù)據(jù)類型取數(shù)的方法:

  • 使用astype()函數(shù)進(jìn)行強(qiáng)制類型轉(zhuǎn)換
  • 通過(guò)自定義函數(shù)來(lái)進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換
  • 使用Pandas提供的函數(shù)如to_numeric()、to_datetime()等進(jìn)行轉(zhuǎn)化
  • select_dtypes函數(shù)的使用
image

Pandas、Python、Numpy各自支持的數(shù)據(jù)類型

下表中展示的是Pandas、Python和Numpy中支持的數(shù)據(jù)類型,可以看到pandas中支持的類型是最豐富的的。

image

模擬數(shù)據(jù)

導(dǎo)入數(shù)據(jù)

下面是模擬的一份數(shù)據(jù),包含多個(gè)字段名稱

image
import pandas as pd
import numpy as np

# 讀取數(shù)據(jù)
df = pd.read_csv("數(shù)據(jù)類型操作.csv")
df
image

查看數(shù)據(jù)的字段類型:

image

數(shù)據(jù)類型查看

df.dtypes # 各字段的數(shù)據(jù)類型
df.team.dtype # 某個(gè)字段的類型
s.dtype # Series 的類型
df.dtypes.value_counts() # 各類型有多少個(gè)字段

實(shí)際案例

字符型轉(zhuǎn)成數(shù)值型

比如我們想在數(shù)據(jù)上進(jìn)行一些操作,比如將"2019年"、和"2020年"的數(shù)據(jù)相加:很明顯數(shù)據(jù)不是我們想要的結(jié)果。

根本原因:這兩個(gè)字段是字符類型,進(jìn)行+操作,是直接將里面的內(nèi)容拼接在一起,而不是里面數(shù)值的相加。

image

正確的操作:

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
image

2、查看數(shù)據(jù)類型

生成的兩個(gè)新字段仍然是字符類型,不能直接相加

image

3、將數(shù)字表現(xiàn)型的字符型數(shù)據(jù)轉(zhuǎn)成數(shù)值型

有兩種方法實(shí)現(xiàn)這種需求:

  • pd.astype("float") :指定類型
  • to_numeric():直接轉(zhuǎn)化
##  字符類型的數(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
image

3、將兩個(gè)新的字段相加

df["前兩年之和"] = df["2020年_新"] + df["2019年_新"]
df
image

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

image

數(shù)值型轉(zhuǎn)成字符型

求出2020年的增長(zhǎng)率:

df["增長(zhǎng)率"] = df["前兩年之差"] / df["2019年_新"]
df
image

現(xiàn)在整個(gè)增長(zhǎng)率是float的數(shù)值型,我們想把它轉(zhuǎn)成%的形式,也就是字符類型的數(shù)據(jù):

顧客姓名        object
顧客編碼         int64
客戶部門(mén)        object
客戶組別       float64
2019年       object
2020年       object
日            int64
月            int64
年            int64
是否大客戶       object
2020年_新      int64
2019年_新      int64
前兩年之和        int64
前兩年之差        int64
增長(zhǎng)率        float64     # 數(shù)值型數(shù)據(jù)
dtype: object

在這里也是兩種方法滿足上面的需求:

  • 方法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
image
顧客姓名        object
顧客編碼         int64
客戶部門(mén)        object
客戶組別       float64
2019年       object
2020年       object
日            int64
月            int64
年            int64
是否大客戶       object
2020年_新      int64
2019年_新      int64
前兩年之和        int64
前兩年之差        int64
增長(zhǎng)率        float64
增長(zhǎng)率1        object   #  兩個(gè)字符類型的數(shù)據(jù)
增長(zhǎng)率2        object
dtype: object

數(shù)值型數(shù)據(jù)存在缺失值

如果某個(gè)字段中大部分的數(shù)據(jù)都是數(shù)值型,但是存在少量的缺失值的情況,可以使用下面的方法進(jìn)行轉(zhuǎn)化:

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

數(shù)值型類型轉(zhuǎn)成時(shí)間類型

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

image

1、上面的日、月、年現(xiàn)在是數(shù)值類型的數(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
image

3、通過(guò)pd.to_datetime轉(zhuǎn)成pandas中的時(shí)間類型數(shù)據(jù)

df["生日"] = df["生日"].apply(lambda x: pd.to_datetime(x,format="%Y-%m-%d"))
df.dtypes
image

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

pd.to_datetime(df[['year', 'month', 'day']]) # 組合成日期
image
image

布爾值判斷使用

比如在是否為大客戶中,我們想將Y換成True,N換成False,可以通過(guò)np.where來(lái)是實(shí)現(xiàn):

df["是否大客戶"] = np.where(df["是否大客戶"] == "Y", True, False)
df
image

讀取文件直接轉(zhuǎn)換

在使用pandas讀取文件的時(shí)候,我們可以直接改變數(shù)據(jù)類型,使用參數(shù)是converters:

df0 = pd.read_csv("數(shù)據(jù)類型操作.csv",
                  converters={
                    "顧客編碼":str,  # 指定改變的函數(shù)
                    "2019年":lambda x:float(x.split("元")[0]),  # 切割函數(shù)
                    "2020年":lambda x:float(x.replace("元","")),  # 替換函數(shù)
                    "客戶組別":lambda x: pd.to_numeric(x, errors='coerce'), 
                    "是否大客戶":lambda x:np.where(x == "Y",True,False)
                  }
                 )
df0 
image

根據(jù)數(shù)據(jù)類型取數(shù)

我們看看df數(shù)據(jù)中存在的數(shù)據(jù)類型:object、int64、float64、bool、datetime64[ns]

df.dtypes

# 結(jié)果
顧客姓名               object
顧客編碼                int64
客戶部門(mén)               object
客戶組別              float64
2019年              object
2020年              object
日                  object
月                  object
年                  object
是否大客戶                bool
2020年_新             int64
2019年_新             int64
前兩年之和               int64
前兩年之差               int64
增長(zhǎng)率               float64
增長(zhǎng)率1               object
增長(zhǎng)率2               object
生日         datetime64[ns]
dtype: object

包含數(shù)據(jù)類型

df.select_dtypes(include=["object"])  # 包含object類型的數(shù)據(jù)
image

也可以同時(shí)篩選包含多個(gè)數(shù)據(jù)類型:

df.select_dtypes(include=["object","bool"])
image

不包含數(shù)據(jù)類型

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

同時(shí)排除多個(gè)字段數(shù)據(jù)類型:

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

總結(jié)

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容