這篇文章給大家分享的是有關(guān)Pandas如何實現(xiàn)數(shù)據(jù)類型轉(zhuǎn)換的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
創(chuàng)新互聯(lián)公司是一家專業(yè)提供橋西企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站設(shè)計、成都做網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)、HTML5、小程序制作等業(yè)務(wù)。10年已為橋西眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站設(shè)計公司優(yōu)惠進行中。前言
Pandas是Python當中重要的數(shù)據(jù)分析工具,利用Pandas進行數(shù)據(jù)分析時,確保使用正確的數(shù)據(jù)類型是非常重要的,否則可能會導(dǎo)致一些不可預(yù)知的錯誤發(fā)生。
Pandas 的數(shù)據(jù)類型:數(shù)據(jù)類型本質(zhì)上是編程語言用來理解如何存儲和操作數(shù)據(jù)的內(nèi)部結(jié)構(gòu)。例如,一個程序需要理解你可以將兩個數(shù)字加起來,比如 5 + 10 得到 15?;蛘撸绻莾蓚€字符串,比如「cat」和「hat」,你可以將它們連接(加)起來得到「cathat」。尚學(xué)堂?百戰(zhàn)程序員陳老師指出有關(guān) Pandas 數(shù)據(jù)類型的一個可能令人困惑的地方是,Pandas、Python 和 numpy 的數(shù)據(jù)類型之間有一些重疊。
大多數(shù)情況下,你不必擔(dān)心是否應(yīng)該明確地將熊貓類型強制轉(zhuǎn)換為對應(yīng)的 NumPy 類型。一般來說使用 Pandas 的默認 int64 和 float64 就可以。我列出此表的唯一原因是,有時你可能會在代碼行間或自己的分析過程中看到 Numpy 的類型。
數(shù)據(jù)類型是在你遇到錯誤或意外結(jié)果之前并不會關(guān)心的事情之一。不過當你將新數(shù)據(jù)加載到 Pandas 進行進一步分析時,這也是你應(yīng)該檢查的第一件事情。
筆者使用Pandas已經(jīng)有一段時間了,但是還是會在一些小問題上犯錯誤,追根溯源發(fā)現(xiàn)在對數(shù)據(jù)進行操作時某些特征列并不是Pandas所能處理的類型。因此本文將討論一些小技巧如何將Python的基本數(shù)據(jù)類型轉(zhuǎn)化為Pandas所能處理的數(shù)據(jù)類型。
Pandas、Numpy、Python各自支持的數(shù)據(jù)類型
從上述表格中可以看出Pandas支持的數(shù)據(jù)類型最為豐富,在某種情形下Numpy的數(shù)據(jù)類型可以和Pandas的數(shù)據(jù)類型相互轉(zhuǎn)化,畢竟Pandas庫是在Numpy的基礎(chǔ)之上開發(fā)的的。
引入實際數(shù)據(jù)進行分析
數(shù)據(jù)類型是你平??赡懿惶P(guān)心,直到得到了錯誤的結(jié)果才映像深刻的東西,因此在這里引入一個實際數(shù)據(jù)分析的例子來加深理解。
import numpy as np import pandas as pd data = pd.read_csv('data.csv', encoding='gbk') #因為數(shù)據(jù)中含有中文數(shù)據(jù) data
數(shù)據(jù)加載完畢,如果現(xiàn)在想要在該數(shù)據(jù)上進行一些操作,比如把數(shù)據(jù)列2016、2017對應(yīng)項相加。
data['2016'] + data['2017'] #想當然的做法
從結(jié)果來看并沒有像想象中那樣數(shù)值對應(yīng)相加,這是因為在Pandas中object類型相加等價于Python中的字符串相加。
data.info() #在對數(shù)據(jù)進行處理之前應(yīng)該先查看加載數(shù)據(jù)的相關(guān)信息
在看到加載數(shù)據(jù)的相關(guān)信息后可以發(fā)現(xiàn)如下幾個問題:
客戶編號的數(shù)據(jù)類型是int64而不是object類型
2016、2017列的數(shù)據(jù)類型是object而不是數(shù)值類型(int64、float64)
增長率、所屬組的數(shù)據(jù)類型應(yīng)該為數(shù)值類型而不是object類型
year、month、day的數(shù)據(jù)類型應(yīng)該為datetime64類型而不是object類型
Pandas中進行數(shù)據(jù)類型轉(zhuǎn)換有三種基本方法:
使用astype()函數(shù)進行強制類型轉(zhuǎn)換
自定義函數(shù)進行數(shù)據(jù)類型轉(zhuǎn)換
使用Pandas提供的函數(shù)如to_numeric()、to_datetime()
使用astype()函數(shù)進行類型轉(zhuǎn)換
對數(shù)據(jù)列進行數(shù)據(jù)類型轉(zhuǎn)換最簡單的方法就是使用astype()函數(shù)
data['客戶編號'].astype('object') data['客戶編號'] = data['客戶編號'].astype('object') #對原始數(shù)據(jù)進行轉(zhuǎn)換并覆蓋原始數(shù)據(jù)列
上面的結(jié)果看起來很不錯,接下來給出幾個astype()函數(shù)作用于列數(shù)據(jù)但失效的例子
data['2017'].astype('float')
data['所屬組'].astype('int')
從上面兩個例子可以看出,當待轉(zhuǎn)換列中含有不能轉(zhuǎn)換的特殊值時(例子中¥,ErrorValue等)astype()函數(shù)將失效。有些時候astype()函數(shù)執(zhí)行成功了也并不一定代表著執(zhí)行結(jié)果符合預(yù)期(神坑!)
data['狀態(tài)'].astype('bool')
乍一看,結(jié)果看起來不錯,但仔細觀察后,會發(fā)現(xiàn)一個大問題。那就是所有的值都被替換為True了,但是該列中包含好幾個N標志,所以astype()函數(shù)在該列也是失效的。
總結(jié)一下astype()函數(shù)有效的情形:
數(shù)據(jù)列中的每一個單位都能簡單的解釋為數(shù)字(2, 2.12等)
數(shù)據(jù)列中的每一個單位都是數(shù)值類型且向字符串object類型轉(zhuǎn)換
如果數(shù)據(jù)中含有缺失值、特殊字符astype()函數(shù)可能失效。
使用自定義函數(shù)進行數(shù)據(jù)類型轉(zhuǎn)換
該方法特別適用于待轉(zhuǎn)換數(shù)據(jù)列的數(shù)據(jù)較為復(fù)雜的情形,可以通過構(gòu)建一個函數(shù)應(yīng)用于數(shù)據(jù)列的每一個數(shù)據(jù),并將其轉(zhuǎn)換為適合的數(shù)據(jù)類型。
對于上述數(shù)據(jù)中的貨幣,需要將它轉(zhuǎn)換為float類型,因此可以寫一個轉(zhuǎn)換函數(shù):
def convert_currency(value): """ 轉(zhuǎn)換字符串數(shù)字為float類型 - 移除 ¥ , - 轉(zhuǎn)化為float類型 """ new_value = value.replace(',', '').replace('¥', '') return np.float(new_value)
現(xiàn)在可以使用Pandas的apply函數(shù)通過covert_currency函數(shù)應(yīng)用于2016列中的所有數(shù)據(jù)中。
data['2016'].apply(convert_currency)
該列所有的數(shù)據(jù)都轉(zhuǎn)換成對應(yīng)的數(shù)值類型了,因此可以對該列數(shù)據(jù)進行常見的數(shù)學(xué)操作了。如果利用lambda表達式改寫一下代碼,可能會比較簡潔但是對新手不太友好。
data['2016'].apply(lambda x: x.replace('¥', '').replace(',', '')).astype('float')
當函數(shù)需要重復(fù)應(yīng)用于多個列時,個人推薦使用第一種方法,先定義函數(shù)還有一個好處就是可以搭配read_csv()函數(shù)使用(后面介紹)。
#2016、2017列完整的轉(zhuǎn)換代碼 data['2016'] = data['2016'].apply(convert_currency) data['2017'] = data['2017'].apply(convert_currency)
同樣的方法運用于增長率,首先構(gòu)建自定義函數(shù)
def convert_percent(value): """ 轉(zhuǎn)換字符串百分數(shù)為float類型小數(shù) - 移除 % - 除以100轉(zhuǎn)換為小數(shù) """ new_value = value.replace('%', '') return float(new_value) / 100
使用Pandas的apply函數(shù)通過covert_percent函數(shù)應(yīng)用于增長率列中的所有數(shù)據(jù)中。
data['增長率'].apply(convert_percent)
使用lambda表達式:
data['增長率'].apply(lambda x: x.replace('%', '')).astype('float') / 100
結(jié)果都相同:
為了轉(zhuǎn)換狀態(tài)列,可以使用Numpy中的where函數(shù),把值為Y的映射成True,其他值全部映射成False。
data['狀態(tài)'] = np.where(data['狀態(tài)'] == 'Y', True, False)
同樣的你也可以使用自定義函數(shù)或者使用lambda表達式,這些方法都可以完美的解決這個問題,這里只是多提供一種思路。
利用Pandas的一些輔助函數(shù)進行類型轉(zhuǎn)換
Pandas的astype()函數(shù)和復(fù)雜的自定函數(shù)之間有一個中間段,那就是Pandas的一些輔助函數(shù)。這些輔助函數(shù)對于某些特定數(shù)據(jù)類型的轉(zhuǎn)換非常有用(如to_numeric()、to_datetime())。所屬組數(shù)據(jù)列中包含一個非數(shù)值,用astype()轉(zhuǎn)換出現(xiàn)了錯誤,然而用to_numeric()函數(shù)處理就優(yōu)雅很多。
pd.to_numeric(data['所屬組'], errors='coerce').fillna(0)
可以看到,非數(shù)值被替換成0.0了,當然這個填充值是可以選擇的,具體文檔見
pandas.to_numeric - pandas 0.22.0 documentation
Pandas中的to_datetime()函數(shù)可以把單獨的year、month、day三列合并成一個單獨的時間戳。
pd.to_datetime(data[['day', 'month', 'year']])
完成數(shù)據(jù)列的替換
data['new_date'] = pd.to_datetime(data[['day', 'month', 'year']]) #新產(chǎn)生的一列數(shù)據(jù) data['所屬組'] = pd.to_numeric(data['所屬組'], errors='coerce').fillna(0)
到這里所有的數(shù)據(jù)列都轉(zhuǎn)換完畢,最終的數(shù)據(jù)顯示:
在讀取數(shù)據(jù)時就對數(shù)據(jù)類型進行轉(zhuǎn)換,一步到位
data2 = pd.read_csv("data.csv", converters={ '客戶編號': str, '2016': convert_currency, '2017': convert_currency, '增長率': convert_percent, '所屬組': lambda x: pd.to_numeric(x, errors='coerce'), '狀態(tài)': lambda x: np.where(x == "Y", True, False) }, encoding='gbk')
在這里也體現(xiàn)了使用自定義函數(shù)比lambda表達式要方便很多。(大部分情況下lambda還是很簡潔的,筆者自己也很喜歡使用)
感謝各位的閱讀!關(guān)于“Pandas如何實現(xiàn)數(shù)據(jù)類型轉(zhuǎn)換”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!