pandas 數(shù)據(jù)類型轉(zhuǎn)換的實(shí)現(xiàn)
數(shù)據(jù)處理過程的數(shù)據(jù)類型
當(dāng)利用pandas進(jìn)行數(shù)據(jù)處理的時(shí)候,經(jīng)常會遇到數(shù)據(jù)類型的問題,當(dāng)拿到數(shù)據(jù)的時(shí)候,首先需要確定拿到的是正確類型的數(shù)據(jù),一般通過數(shù)據(jù)類型的轉(zhuǎn)化,這篇文章就介紹pandas里面的數(shù)據(jù)類型(data types也就是常用的dtyps),以及pandas與numpy之間的數(shù)據(jù)對應(yīng)關(guān)系。

主要介紹object,int64,float64,datetime64,bool等幾種類型,category與timedelta兩種類型會單獨(dú)的在其他文章中進(jìn)行介紹。當(dāng)然本文中也會涉及簡單的介紹。
數(shù)據(jù)類型的問題一般都是出了問題之后才會發(fā)現(xiàn)的,所以有了一些經(jīng)驗(yàn)之后就會拿到數(shù)據(jù)之后,就直接看數(shù)據(jù)類型,是否與自己想要處理的數(shù)據(jù)格式一致,這樣可以從一開始避免一些尷尬的問題出現(xiàn)。那么我們以一個(gè)簡單的例子,利用jupyter notebook進(jìn)行一個(gè)數(shù)據(jù)類型的介紹。
####按照慣例導(dǎo)入兩個(gè)常用的數(shù)據(jù)處理的包,numpy與pandas
import numpy as np
import pandas as pd
# 從csv文件讀取數(shù)據(jù),數(shù)據(jù)表格中只有5行,里面包含了float,string,int三種數(shù)據(jù)python類型,也就是分別對應(yīng)的pandas的float64,object,int64
# csv文件中共有六列,第一列是表頭,其余是數(shù)據(jù)。
df = pd.read_csv("sales_data_types.csv")
print(df)
Customer Number Customer Name 2016 2017 \
0 10002 Quest Industries $125,000.00 $162,500.00
1 552278 Smith Plumbing $920,000.00 $1,012,000.00
2 23477 ACME Industrial $50,000.00 $62,500.00
3 24900 Brekke LTD $350,000.00 $490,000.00
4 651029 Harbor Co $15,000.00 $12,750.00Percent Growth Jan Units Month Day Year Active
0 30.00% 500 1 10 2015 Y
1 10.00% 700 6 15 2014 Y
2 25.00% 125 3 29 2016 Y
3 4.00% 75 10 27 2015 Y
4 -15.00% Closed 2 2 2014 N
df.dtypes
Customer Number int64
Customer Name object
2016 object
2017 object
Percent Growth object
Jan Units object
Month int64
Day int64
Year int64
Active object
dtype: object
# 假如想得到2016年與2017年的數(shù)據(jù)總和,可以嘗試,但并不是我們需要的答案,因?yàn)檫@兩列中的數(shù)據(jù)類型是object,執(zhí)行該操作之后,得到是一個(gè)更加長的字符串, # 當(dāng)然我們可以通過df.info() 來獲得關(guān)于數(shù)據(jù)框的更多的詳細(xì)信息, df['2016']+df['2017']
0 $125,000.00 $162,500.00
1 $920,000.00 $1,012,000.00
2 $50,000.00 $62,500.00
3 $350,000.00 $490,000.00
4 $15,000.00 $12,750.00
dtype: object
df.info() # Customer Number 列是float64,然而應(yīng)該是int64 # 2016 2017兩列的數(shù)據(jù)是object,并不是float64或者int64格式 # Percent以及Jan Units 也是objects而不是數(shù)字格式 # Month,Day以及Year應(yīng)該轉(zhuǎn)化為datetime64[ns]格式 # Active 列應(yīng)該是布爾值 # 如果不做數(shù)據(jù)清洗,很難進(jìn)行下一步的數(shù)據(jù)分析,為了進(jìn)行數(shù)據(jù)格式的轉(zhuǎn)化,pandas里面有三種比較常用的方法 # 1. astype()強(qiáng)制轉(zhuǎn)化數(shù)據(jù)類型 # 2. 通過創(chuàng)建自定義的函數(shù)進(jìn)行數(shù)據(jù)轉(zhuǎn)化 # 3. pandas提供的to_nueric()以及to_datetime()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 10 columns):
Customer Number 5 non-null int64
Customer Name 5 non-null object
2016 5 non-null object
2017 5 non-null object
Percent Growth 5 non-null object
Jan Units 5 non-null object
Month 5 non-null int64
Day 5 non-null int64
Year 5 non-null int64
Active 5 non-null object
dtypes: int64(4), object(6)
memory usage: 480.0+ bytes
首先介紹最常用的astype()
比如可以通過astype()將第一列的數(shù)據(jù)轉(zhuǎn)化為整數(shù)int類型
df['Customer Number'].astype("int")
# 這樣的操作并沒有改變原始的數(shù)據(jù)框,而只是返回的一個(gè)拷貝
0 10002
1 552278
2 23477
3 24900
4 651029
Name: Customer Number, dtype: int32
# 想要真正的改變數(shù)據(jù)框,通常需要通過賦值來進(jìn)行,比如
df["Customer Number"] = df["Customer Number"].astype("int")
print(df)
print("--------"*10)
print(df.dtypes)
Customer Number Customer Name 2016 2017 \
0 10002 Quest Industries $125,000.00 $162,500.00
1 552278 Smith Plumbing $920,000.00 $1,012,000.00
2 23477 ACME Industrial $50,000.00 $62,500.00
3 24900 Brekke LTD $350,000.00 $490,000.00
4 651029 Harbor Co $15,000.00 $12,750.00Percent Growth Jan Units Month Day Year Active
0 30.00% 500 1 10 2015 Y
1 10.00% 700 6 15 2014 Y
2 25.00% 125 3 29 2016 Y
3 4.00% 75 10 27 2015 Y
4 -15.00% Closed 2 2 2014 N
--------------------------------------------------------------------------------
Customer Number int32
Customer Name object
2016 object
2017 object
Percent Growth object
Jan Units object
Month int64
Day int64
Year int64
Active object
dtype: object
# 通過賦值在原始的數(shù)據(jù)框基礎(chǔ)上進(jìn)行了數(shù)據(jù)轉(zhuǎn)化,可以重新看一下我們新生成的數(shù)據(jù)框 print(df)
Customer Number Customer Name 2016 2017 \
0 10002 Quest Industries $125,000.00 $162,500.00
1 552278 Smith Plumbing $920,000.00 $1,012,000.00
2 23477 ACME Industrial $50,000.00 $62,500.00
3 24900 Brekke LTD $350,000.00 $490,000.00
4 651029 Harbor Co $15,000.00 $12,750.00Percent Growth Jan Units Month Day Year Active
0 30.00% 500 1 10 2015 Y
1 10.00% 700 6 15 2014 Y
2 25.00% 125 3 29 2016 Y
3 4.00% 75 10 27 2015 Y
4 -15.00% Closed 2 2 2014 N
# 然后像2016,2017 Percent Growth,Jan Units 這幾列帶有特殊符號的object是不能直接通過astype("flaot)方法進(jìn)行轉(zhuǎn)化的,
# 這與python中的字符串轉(zhuǎn)化為浮點(diǎn)數(shù),都要求原始的字符都只能含有數(shù)字本身,不能含有其他的特殊字符
# 我們可以試著將將Active列轉(zhuǎn)化為布爾值,看一下到底會發(fā)生什么,五個(gè)結(jié)果全是True,說明并沒有起到什么作用
#df["Active"].astype("bool")
df['2016'].astype('float')
ValueError Traceback (most recent call last)
<ipython-input-19-47cc9d68cd65> in <module>()
----> 1 df['2016'].astype('float')
C:\Anaconda3\lib\site-packages\pandas\core\generic.py in astype(self, dtype, copy, raise_on_error, **kwargs)
3052 # else, only a single dtype is given
3053 new_data = self._data.astype(dtype=dtype, copy=copy,
-> 3054 raise_on_error=raise_on_error, **kwargs)
3055 return self._constructor(new_data).__finalize__(self)
3056
C:\Anaconda3\lib\site-packages\pandas\core\internals.py in astype(self, dtype, **kwargs)
3187
3188 def astype(self, dtype, **kwargs):
-> 3189 return self.apply('astype', dtype=dtype, **kwargs)
3190
3191 def convert(self, **kwargs):
C:\Anaconda3\lib\site-packages\pandas\core\internals.py in apply(self, f, axes, filter, do_integrity_check, consolidate, **kwargs)
3054
3055 kwargs['mgr'] = self
-> 3056 applied = getattr(b, f)(**kwargs)
3057 result_blocks = _extend_blocks(applied, result_blocks)
3058
C:\Anaconda3\lib\site-packages\pandas\core\internals.py in astype(self, dtype, copy, raise_on_error, values, **kwargs)
459 **kwargs):
460 return self._astype(dtype, copy=copy, raise_on_error=raise_on_error,
--> 461 values=values, **kwargs)
462
463 def _astype(self, dtype, copy=False, raise_on_error=True, values=None,
C:\Anaconda3\lib\site-packages\pandas\core\internals.py in _astype(self, dtype, copy, raise_on_error, values, klass, mgr, **kwargs)
502
503 # _astype_nansafe works fine with 1-d only
--> 504 values = _astype_nansafe(values.ravel(), dtype, copy=True)
505 values = values.reshape(self.shape)
506
C:\Anaconda3\lib\site-packages\pandas\types\cast.py in _astype_nansafe(arr, dtype, copy)
535
536 if copy:
--> 537 return arr.astype(dtype)
538 return arr.view(dtype)
539
ValueError: could not convert string to float: '$15,000.00 '
以上的問題說明了一些問題
- 如果數(shù)據(jù)是純凈的數(shù)據(jù),可以轉(zhuǎn)化為數(shù)字
- astype基本也就是兩種用作,數(shù)字轉(zhuǎn)化為單純字符串,單純數(shù)字的字符串轉(zhuǎn)化為數(shù)字,含有其他的非數(shù)字的字符串是不能通過astype進(jìn)行轉(zhuǎn)化的。
- 需要引入其他的方法進(jìn)行轉(zhuǎn)化,也就有了下面的自定義函數(shù)方法
通過自定義函數(shù)清理數(shù)據(jù)
通過下面的函數(shù)可以將貨幣進(jìn)行轉(zhuǎn)化
def convert_currency(var):
"""
convert the string number to a float
_ 去除$
- 去除逗號,
- 轉(zhuǎn)化為浮點(diǎn)數(shù)類型
"""
new_value = var.replace(",","").replace("$","")
return float(new_value)
# 通過replace函數(shù)將$以及逗號去掉,然后字符串轉(zhuǎn)化為浮點(diǎn)數(shù),讓pandas選擇pandas認(rèn)為合適的特定類型,float或者int,該例子中將數(shù)據(jù)轉(zhuǎn)化為了float64 # 通過pandas中的apply函數(shù)將2016列中的數(shù)據(jù)全部轉(zhuǎn)化 df["2016"].apply(convert_currency)
0 125000.0
1 920000.0
2 50000.0
3 350000.0
4 15000.0
Name: 2016, dtype: float64
# 當(dāng)然可以通過lambda 函數(shù)將這個(gè)比較簡單的函數(shù)一行帶過
df["2016"].apply(lambda x: x.replace(",","").replace("$","")).astype("float64")
0 125000.0
1 920000.0
2 50000.0
3 350000.0
4 15000.0
Name: 2016, dtype: float64
#同樣可以利用lambda表達(dá)式將PercentGrowth進(jìn)行數(shù)據(jù)清理
df["Percent Growth"].apply(lambda x: x.replace("%","")).astype("float")/100
0 0.30
1 0.10
2 0.25
3 0.04
4 -0.15
Name: Percent Growth, dtype: float64
# 同樣可以通過自定義函數(shù)進(jìn)行解決,結(jié)果同上 # 最后一個(gè)自定義函數(shù)是利用np.where() function 將Active 列轉(zhuǎn)化為布爾值。 df["Active"] = np.where(df["Active"] == "Y", True, False) df["Active"]
0 True
1 True
2 True
3 True
4 False
Name: Active, dtype: bool
# 此時(shí)可查看一下數(shù)據(jù)格式
df["2016"]=df["2016"].apply(lambda x: x.replace(",","").replace("$","")).astype("float64")
df["2017"]=df["2017"].apply(lambda x: x.replace(",","").replace("$","")).astype("float64")
df["Percent Growth"]=df["Percent Growth"].apply(lambda x: x.replace("%","")).astype("float")/100
df.dtypes
Customer Number int32
Customer Name object
2016 float64
2017 float64
Percent Growth float64
Jan Units object
Month int64
Day int64
Year int64
Active bool
dtype: object
# 再次查看DataFrame # 此時(shí)只有Jan Units中格式需要轉(zhuǎn)化,以及年月日的合并,可以利用pandas中自帶的幾個(gè)函數(shù)進(jìn)行處理 print(df)
Customer Number Customer Name 2016 2017 Percent Growth \
0 10002 Quest Industries 125000.0 162500.0 0.30
1 552278 Smith Plumbing 920000.0 1012000.0 0.10
2 23477 ACME Industrial 50000.0 62500.0 0.25
3 24900 Brekke LTD 350000.0 490000.0 0.04
4 651029 Harbor Co 15000.0 12750.0 -0.15Jan Units Month Day Year Active
0 500 1 10 2015 True
1 700 6 15 2014 True
2 125 3 29 2016 True
3 75 10 27 2015 True
4 Closed 2 2 2014 False
利用pandas中函數(shù)進(jìn)行處理
# pandas中pd.to_numeric()處理Jan Units中的數(shù)據(jù) pd.to_numeric(df["Jan Units"],errors='coerce').fillna(0)
0 500.0
1 700.0
2 125.0
3 75.0
4 0.0
Name: Jan Units, dtype: float64
# 最后利用pd.to_datatime()將年月日進(jìn)行合并 pd.to_datetime(df[['Month', 'Day', 'Year']])
0 2015-01-10
1 2014-06-15
2 2016-03-29
3 2015-10-27
4 2014-02-02
dtype: datetime64[ns]
# 做到這里不要忘記重新賦值,否則原始數(shù)據(jù)并沒有變化 df["Jan Units"] = pd.to_numeric(df["Jan Units"],errors='coerce') df["Start_date"] = pd.to_datetime(df[['Month', 'Day', 'Year']])
| Customer Number | Customer Name | 2016 | 2017 | Percent Growth | Jan Units | Month | Day | Year | Active | Start_date | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 10002 | Quest Industries | 125000.0 | 162500.0 | 0.30 | 500.0 | 1 | 10 | 2015 | True | 2015-01-10 |
| 1 | 552278 | Smith Plumbing | 920000.0 | 1012000.0 | 0.10 | 700.0 | 6 | 15 | 2014 | True | 2014-06-15 |
| 2 | 23477 | ACME Industrial | 50000.0 | 62500.0 | 0.25 | 125.0 | 3 | 29 | 2016 | True | 2016-03-29 |
| 3 | 24900 | Brekke LTD | 350000.0 | 490000.0 | 0.04 | 75.0 | 10 | 27 | 2015 | True | 2015-10-27 |
| 4 | 651029 | Harbor Co | 15000.0 | 12750.0 | -0.15 | NaN | 2 | 2 | 2014 | False | 2014-02-02 |
df.dtypes
Customer Number int32
Customer Name object
2016 float64
2017 float64
Percent Growth float64
Jan Units float64
Month int64
Day int64
Year int64
Active bool
Start_date datetime64[ns]
dtype: object
# 將這些轉(zhuǎn)化整合在一起
def convert_percent(val):
"""
Convert the percentage string to an actual floating point percent
- Remove %
- Divide by 100 to make decimal
"""
new_val = val.replace('%', '')
return float(new_val) / 100
df_2 = pd.read_csv("sales_data_types.csv",dtype={"Customer_Number":"int"},converters={
"2016":convert_currency,
"2017":convert_currency,
"Percent Growth":convert_percent,
"Jan Units":lambda x:pd.to_numeric(x,errors="coerce"),
"Active":lambda x: np.where(x=="Y",True,False)
})
df_2.dtypes
Customer Number int64
Customer Name object
2016 float64
2017 float64
Percent Growth float64
Jan Units float64
Month int64
Day int64
Year int64
Active bool
dtype: object
df_2
| Customer Number | Customer Name | 2016 | 2017 | Percent Growth | Jan Units | Month | Day | Year | Active | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 10002 | Quest Industries | 125000.0 | 162500.0 | 0.30 | 500.0 | 1 | 10 | 2015 | True |
| 1 | 552278 | Smith Plumbing | 920000.0 | 1012000.0 | 0.10 | 700.0 | 6 | 15 | 2014 | True |
| 2 | 23477 | ACME Industrial | 50000.0 | 62500.0 | 0.25 | 125.0 | 3 | 29 | 2016 | True |
| 3 | 24900 | Brekke LTD | 350000.0 | 490000.0 | 0.04 | 75.0 | 10 | 27 | 2015 | True |
| 4 | 651029 | Harbor Co | 15000.0 | 12750.0 | -0.15 | NaN | 2 | 2 | 2014 | False |
至此,pandas里面數(shù)據(jù)類型目前還有timedelta以及category兩個(gè),之后會著重介紹category類型,這是類型是參考了R中的category設(shè)計(jì)的,在pandas 0.16 之后添加的,之后還會根據(jù)需要進(jìn)行整理pandas的常用方法。
到此這篇關(guān)于pandas 數(shù)據(jù)類型轉(zhuǎn)換的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)pandas 數(shù)據(jù)類型轉(zhuǎn)換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Django之使用celery和NGINX生成靜態(tài)頁面實(shí)現(xiàn)性能優(yōu)化
這篇文章主要介紹了Django之使用celery和NGINX生成靜態(tài)頁面實(shí)現(xiàn)性能優(yōu)化,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
python使用os.listdir和os.walk獲得文件的路徑的方法
本篇文章主要介紹了python使用os.listdir和os.walk獲得文件的路徑的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-12-12
Python?round函數(shù)的基本用法與實(shí)例代碼
round()函數(shù)是Python中用于對浮點(diǎn)數(shù)進(jìn)行四舍五入的內(nèi)置函數(shù),這篇文章詳細(xì)介紹了round()函數(shù)的基本用法、參數(shù)詳解、特殊情況處理以及應(yīng)用場景,并提供了豐富的示例代碼,需要的朋友可以參考下2024-11-11
解決使用pip安裝報(bào)錯(cuò):Microsoft?Visual?C++?14.0?is?required.
對于程序員來說,經(jīng)常pip安裝自己所需要的包,大部分的包基本都能安裝,但是總會遇到包安裝不了的問題,下面這篇文章主要給大家介紹了關(guān)于如何解決使用pip安裝報(bào)錯(cuò):Microsoft?Visual?C++?14.0?is?required.的相關(guān)資料,需要的朋友可以參考下2022-09-09
Python numpy大矩陣運(yùn)算內(nèi)存不足如何解決
這篇文章主要介紹了Python numpy大矩陣運(yùn)算內(nèi)存不足如何解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11
利用Python裁切tiff圖像且讀取tiff,shp文件的實(shí)例
這篇文章主要介紹了利用Python裁切tiff圖像且讀取tiff,shp文件的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03

