pandas數(shù)據(jù)清洗(缺失值和重復值的處理)
前言
pandas對大數(shù)據(jù)有很多便捷的清洗用法,尤其針對缺失值和重復值。缺失值就不用說了,會影響計算,重復值有時候可能并未帶來新的信息反而增加了計算量,所以有時候要進行處理。針對一些文本數(shù)據(jù)可能不合要求的還要進行替換什么的。
首先導入包:
import numpy as np import pandas as pd
缺失值處理
'''一般使用特殊類型 NaN 代表缺失值,可以用 Numpy 可定義它np.NaN/np.nan。在 Pandas 1.0 以后實驗性地使用一個標量 pd.NA 來代表。
如果想把正負無窮也為認是缺失值,可以通過以下全局配置來設定:'''
pandas.options.mode.use_inf_as_na = True #以下數(shù)據(jù) NaN 為缺失值: df=(pd.DataFrame(np.random.randn(5, 3),index=['a', 'c', 'e', 'f', 'h'], columns=['one', 'two', 'three']) .reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])) df

缺失值的判斷
#可以判斷是否缺失值,DataFrame 和 Series 一般都支持。:
# 不是缺失值 df.one.notna()

df.isna() # 是缺失值

df[df.one.notna()]# 進行篩選

#需要注意的是,Numpy 中 np.nan 和 np.nan 不相等,因此不能用 ==/!= 進行對比: None == None # noqa: E711 # True np.nan == np.nan # False None == np.nan # False
其他方法:
df.notna() df['team'].isna() df['team'].isnull()
缺失值統(tǒng)計
df.isnull().sum()#計算每列缺失值個數(shù) df.isnull().sum(1)#計算每行缺失值個數(shù) df.isnull().sum().sum()#總共缺失值個數(shù)
缺失值篩選
df.loc[df.isna().any(1)]# 有缺失值的行 df.loc[:,df.isna().any()] # 有缺失值的列 df.loc[~(df.isna().any(1))] # 沒有缺失值的行 df.loc[:,~(df.isna().any())] # 沒有缺失值的列
缺失值類型
#時間中的缺失值
#對于時間中的缺失值,Pandas 提供了一個 NaT 來表示,并且 NaT 和 NaN 之間是兼容的:
df['timestamp'] = pd.Timestamp('20120101')
df.loc[['a', 'c', 'h'], ['one', 'timestamp']] = np.nan
df.timestamp
#整型中的缺失值,由于 NaN 是浮點型,因此一列甚至缺少一個整數(shù)的整數(shù)列都將轉換為浮點。
pd.Series([1, 2, np.nan, 4], dtype=pd.Int64Dtype())

插入缺失值
#可以使用 None 等方法將內容修改為缺失值: s.loc[0] = None s.loc[1] = np.nan df.two = pd.NA
缺失值填充
首先生成案例數(shù)據(jù):
df = pd.DataFrame([[np.nan, 2, np.nan, 0],
[3, 4, np.nan, 1],
[np.nan, np.nan, np.nan, 5],
[np.nan, 3, np.nan, 4]],
columns=list('ABCD'))
df
fillna(x) 可以將缺失值填充指定的值。以下為幾種常見的填充方法:
df.fillna(0)# 填充為 0
# 填充為指定字符
df.fillna('missing')
df.fillna('暫無')
df.fillna('待補充')
df.one.fillna('暫無') # 指定字段填充
df.one.fillna(0, inplace=Ture) # 使填充內容生效
df.fillna(0, limit=1) # 只替換第一個
values = {'A': 0, 'B': 1, 'C': 2, 'D': 3} # 不同列替換不同的值
df.fillna(value=values)不指定值,使用一定的方法。
#使用 method{‘backfill', ‘bfill', ‘pad', ‘ffill', None}, default None
df.fillna(method='backfill')# 使用上一個有效值填充
df.fillna(method='bfill')# 同 backfill
df.fillna(method='pad')# 把當前值廣播到后邊的缺失值
df.fillna(method='ffill')# 同 pad
#fillna(method='ffill') 可以簡寫為 ffill() , fillna(method='bfill') 可以簡寫為 bfill()使用計算值填充:
# 填充列的平均值 df.fillna(df.mean()) # 對指定列填充平均值 df.fillna(df.mean()['B':'C']) # 填充列的平均值,另外一個方法 df.where(pd.notna(df), df.mean(), axis='columns') #特別的計算: # 第一個非空值 df.fillna(method='bfill').head(1).iloc[0] # 第一個非空值索引 df.notna().idxmax() df.apply(pd.Series.first_valid_index)
插值填充
插值方式,以下是一個非常簡單的示例,其中一個值是缺失的,我們對它進行差值:
s = pd.Series([0, 1,4,9, np.nan, 25]) s.interpolate()

9和25之間的中間點為17,就把缺失值補為了17,這是線性插值。
s.interpolate(method='spline',order=2)

這是二級多項式插值。用X^2這個函數(shù)去插值的,
interpolate() 的具體參數(shù)
'''默認linear 方法,會認為是一條直線。
計算方法:
默認 method=‘linear’ 如果你的數(shù)據(jù)增長速率越來越快,可以選擇 method='quadratic' 二次插值。如果數(shù)據(jù)集呈現(xiàn)出累計分布的樣子,
推薦選擇 method='pchip'。如果需要填補缺省值,以平滑繪圖為目標,推薦選擇 method='akima'。method='akima' 和 method = ‘pchip’,
需要你的環(huán)境中安裝了 Scipy 庫。除此之外,method='barycentric' 和 method='pchip' 同樣也需要 Scipy 才能使用。
使用插值方法,可為:
- linear:線性,忽略索引,并將值等距地對待,這是MultiIndexes支持的唯一方法
- time:時間,以插值給定的時間間隔長度處理每日或更高粒度的數(shù)據(jù)
- index, values:索引,值,使用索引的實際數(shù)值
- pad:使用現(xiàn)有值填寫NaN。
- ‘nearest’, ‘zero’, ‘slinear’, ‘quadratic’, ‘cubic’, ‘spline’, ‘barycentric’, ‘polynomial’:
- 傳遞給 scipy.interpolate.interp1d,這些方法使用索引的數(shù)值。 ‘polynomial’ 和 ‘spline’ 都要求您還指定一個順序(int),
- 例如 df.interpolate(method='polynomial',order=5)
- nearest:最近
- zero:零
- slinear:線性
- quadratic:二次方
- cubic:立方
- spline:花鍵,樣條插值
- barycentric:重心插值
- polynomial:多項式
- ‘krogh’, ‘piecewise_polynomial’, ‘spline’, ‘pchip’, ‘akima’: SciPy 類似名稱的插值方法。
- krogh: 克羅格插值
- piecewise_polynomial: 分段多項式
- spline: 樣條插值
- pchip: 立方插值 (累計分布)
- akima: 阿克瑪插值 (平滑繪圖)
- from_derivatives:指 scipy.interpolate.BPoly.from_derivatives,它替換了 scipy 0.18 中的 piecewise_polynomial 插值方法。
其他參數(shù):
- axis: 插值應用的軸方向,可選擇 {0 or ‘index’, 1 or ‘columns’, None}, 默認為 None
- limitint: 要填充的連續(xù) NaN 的最大數(shù)量, 必須大于 0。
- inplace: 是否將最終結果替換原數(shù)據(jù),默認為 False
- limit_direction: 限制方向,可傳入 {‘forward’, ‘backward’, ‘both’}, 默認 ‘forward’,如果指定了限制,則將沿該方向填充連續(xù)的 NaN
- limit_area: 限制區(qū)域,可傳入 {None, ‘inside’, ‘outside’}, 默認 None,如果指定了限制,則連續(xù)的NaN將被此限制填充
- None: 沒有填充限制
- ‘inside’: 僅填充有效值包圍的NaN(內插)
- ‘outside’: 僅將NaN填充到有效值之外(外推)
- downcast: 可傳入‘infer’ 或者 None, 默認是 None,如果可以向下轉換 dtypes
- **kwargs: 傳遞給插值函數(shù)的關鍵字參數(shù) '''
缺失值刪除
生成案例數(shù)據(jù):
#一般刪除會針對行進行,如一行中有缺失值就會刪除,當然也會有針對列的。
df = pd.DataFrame({"name": ['Alfred', 'Batman', 'Catwoman'],
"toy": [np.nan, 'Batmobile', 'Bullwhip'],
"born": [pd.NaT, pd.Timestamp("1940-04-25"),
pd.NaT]})
df
缺失值刪除 dropna
# 刪除所有有缺失值的行(有一個缺失就刪除) df.dropna() # 刪除所有有缺失值的列 df.dropna(axis='columns') df.dropna(axis=1) # 刪除所有值都缺失的行 df.dropna(how='all') # 不足2個非空值時刪除 df.dropna(thresh=2) # 指定判斷缺失值的列范圍 df.dropna(subset=['name', 'born']) # 使刪除和的結果生效 df.dropna(inplace=True) # 指定列的缺失值刪除 df.toy.dropna()
重復值處理
重復值的尋找主要使用duplicated,語法為:
df.duplicated(subset=None, keep='first')
'''可以返回表示重復行的布爾系列,可以指定列。keep參數(shù)確定要標記的重復項(如果有),選項有:
- first:將除第一次出現(xiàn)的重復值標記為True,默認。
- last:將除最后一次出現(xiàn)的重復值標記為True。
- False:將所有重復值標記為True。'''
生成案例數(shù)據(jù):
df = pd.DataFrame({'brand': ['Yum Yum', 'Yum Yum', 'Indomie', 'Indomie', 'Indomie'],
'style': ['cup', 'cup', 'cup', 'pack', 'pack'],
'rating': [4, 4, 3.5, 15, 5] })
df
重復值查找
#默認情況下,對于每組重復的值,第一次出現(xiàn)都設置為False,所有其他值設置為True。
df.duplicated()

通過使用“ last”,將每組重復值的最后一次出現(xiàn)設置為False,將所有其他重復值設置為True。
df.duplicated(keep='last')

#通過將keep設置為False,所有重復項都為True。
df.duplicated(keep='last')

要在特定列上查找重復項,請使用子集。
df.duplicated(keep=False)

刪除重復值
'''刪除重復值的語法為:
df.drop_duplicates(subset=None, ? ? ? ? ? ? ? ? ? ?keep='first', ? ? ? ? ? ? ? ? ? ?inplace=False, ? ? ? ? ? ? ? ? ? ?ignore_index=False)
subset指定的標簽或標簽序列可選,僅刪除某些列重復項,默認情況為使用所有列,其他有:
- keep:確定要保留的重復項(如果有)
- first : 保留第一次出現(xiàn)的重復項,默認
- last : 保留最后一次出現(xiàn)的重復項。
- False : 刪除所有重復項
- inplac:False,是將副本放置在適當位置還是返回副本
- ignore_inde:如果為True, 則重新分配自然索引(0, 1, …, n - 1)'''
df.drop_duplicates()
#默認情況下,它將基于所有列刪除重復的行。

df.drop_duplicates(subset=['brand'])
#要刪除特定列上的重復項,使用子集

df.drop_duplicates(subset=['brand', 'style'], keep='last')
#刪除重復項并保留最后一次出現(xiàn),請使用keep。

drop刪除數(shù)據(jù)
語法
df.drop(labels=None,axis=0,index=None,columns=None,level=None,inplace=False,errors='raise')
labels表示要刪除的行或者列,多個可以傳入列表:
- axis:表示軸方向,默認0(行)
- index:指定一行或多行
- columns:指定列
- level:指定多層索引
- inplace:立即修改
df.drop([2,4])#刪除指定行

df.drop(['brand','rating'],axis=1)#刪除指定列 df.drop(columns=['brand','rating'])#同上

數(shù)據(jù)替換replace
有時候想把數(shù)據(jù)替換為指定的值,空值缺失值都可以替換
#指定值替換,以下是在 Series 中將 0 替換為 5:
ser = pd.Series([0., 1., 2., 3., 4.])
ser.replace(0, 5)
#也可以批量替換:
# 一一對應進行替換
ser.replace([0, 1, 2, 3, 4], [4, 3, 2, 1, 0])
# 用字典映射對應替換值
ser.replace({0: 10, 1: 100})
# 將 a 列的 0 b 列中的 5 替換為 100
df.replace({'a': 0, 'b': 5}, 100)
# 指定列里的替換規(guī)劃
df.replace({'a': {0: 100, 4: 400}})除了給定指定值進行替換,我們還可以指定一些替換的方法:
# 將 1,2,3 替換為它們前一個值(0) ser.replace([1, 2, 3], method='pad') # ffill 是它同義詞 # 將 1,2,3 替換為它們后一個值(4) ser.replace([1, 2, 3], method='bfill')
字符替換
#如果遇到字符比較復雜的內容,就是使用正則(默認沒有開啟)進行匹配:
# 把 bat 替換為 new
df.replace(to_replace='bat', value='new')
# 利用正則將 ba 開頭的替換為 new
df.replace(to_replace=r'^ba.$', value='new', regex=True)
# 如果多列規(guī)則不一的情況下可以按以下格式對應傳入
df.replace({'A': r'^ba.$'}, {'A': 'new'}, regex=True)
# 多個規(guī)則替換為同一個值
df.replace(regex=[r'^ba.$', 'foo'], value='new')
# 直接多個正則及對應的替換內容
df.replace(regex={r'^ba.$': 'new', 'foo': 'xyz'})缺失值替換
替換可以處理缺失值相關的問題,如我們可以將無效的值先替換為 nan,再做缺失值處理:
生成案例數(shù)據(jù)‘
d = {'a': list(range(4)),
'b': list('ab..'),
'c': ['a', 'b', np.nan, 'd']}
df = pd.DataFrame(d)
df
一些用法:
# 將.替換為 nan,(也可以替換為 None)
df.replace('.', np.nan)
# 使用正則,將空格和點等替換為 nan
df.replace(r'\s*\.\s*', np.nan, regex=True)
# 對應替換,a 換 b, 點換 nan
df.replace(['a', '.'], ['b', np.nan])
# 點換 dot, a 換 astuff (第一位+)
df.replace([r'\.', r'(a)'], ['dot', r'\1stuff'], regex=True)
# b 中的點要替換,替換為 b 替換規(guī)則為 nan,可以多列
df.replace({'b': '.'}, {'b': np.nan})
# 使用正則
df.replace({'b': r'\s*\.\s*'}, {'b': np.nan}, regex=True)
# b列的 b 值換為空
df.replace({'b': {'b': r''}}, regex=True)
# b 列的點空格等換 nan
df.replace(regex={'b': {r'\s*\.\s*': np.nan}})
# b列點等+ty
df.replace({'b': r'\s*(\.)\s*'},
{'b': r'\1ty'},regex=True)
# 多個正則規(guī)則(a,b,. 都換為缺失)
df.replace([r'\s*\.\s*', r'a|b'], np.nan, regex=True)
# 用參數(shù)名傳參
df.replace(regex=[r'\s*\.\s*', r'a|b'], value=np.nan)數(shù)字替換
生成數(shù)據(jù):
df = pd.DataFrame(np.random.randn(5, 2)) df[np.random.rand(df.shape[0]) > 0.5] = 1.5 df

# 將 1.5 替換為 nan df.replace(1.5, np.nan) # 將1.5換為 nan, 同時于左上角的值換為 a df.replace([1.5, df.iloc[0, 0]], [np.nan, 'a']) # 使替換生效 df.replace(1.5, np.nan, inplace=True)
數(shù)據(jù)裁剪df.clip()
#對一些極端值,如過大或者過小,可以使用 df.clip(lower, upper) 來修剪,當數(shù)據(jù)大于 upper 時,使用 upper 的值,
#小于 lower 時用 lower 的值,就像 numpy.clip 方法一樣。
df = pd.DataFrame({'a': [-1, 2, 5], 'b': [6, 1, -3]})
df
修剪成最大為3最小為0
df.clip(0,3)

用來處理數(shù)據(jù)里面的異常值什么的還是很方便的。
到此這篇關于pandas數(shù)據(jù)清洗(缺失值和重復值的處理)的文章就介紹到這了,更多相關pandas數(shù)據(jù)清洗內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- 基于pandas數(shù)據(jù)清洗的實現(xiàn)示例
- 利用pandas進行數(shù)據(jù)清洗的7種方式
- Pandas數(shù)據(jù)清洗和預處理的實現(xiàn)示例
- Pandas數(shù)據(jù)清洗的實現(xiàn)
- Python數(shù)據(jù)清洗之利用pandas篩選數(shù)據(jù)詳解
- Pandas數(shù)據(jù)清洗函數(shù)總結
- pandas數(shù)據(jù)清洗實現(xiàn)刪除的項目實踐
- 詳解Python如何利用Pandas與NumPy進行數(shù)據(jù)清洗
- 利用pandas進行數(shù)據(jù)清洗的方法
- Pandas 數(shù)據(jù)處理,數(shù)據(jù)清洗詳解
- pandas數(shù)據(jù)清洗,排序,索引設置,數(shù)據(jù)選取方法
相關文章
python opencv鼠標畫矩形框之cv2.rectangle()函數(shù)
鼠標操作屬于用戶接口設計,以前一直使用Qt來做,但是如果只需要簡單的鼠標,鍵盤操作,直接調用opencv庫的函數(shù)也未嘗不可,下面這篇文章主要給大家介紹了關于python opencv鼠標畫矩形框cv2.rectangle()函數(shù)的相關資料,需要的朋友可以參考下2021-10-10
python爬蟲使用requests發(fā)送post請求示例詳解
這篇文章主要介紹了python爬蟲使用requests發(fā)送post請求示例詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-08-08
Python中的測試模塊unittest和doctest的使用教程
這篇文章主要介紹了Python中的測試模塊unittest和doctest的使用教程,本文來自于IBM官方網(wǎng)站技術文檔,需要的朋友可以參考下2015-04-04
python實現(xiàn)按任意鍵繼續(xù)執(zhí)行程序
本文給大家分享的是如何使用Python腳本實現(xiàn)按任意鍵繼續(xù)執(zhí)行程序的代碼,非常的簡單實用,有需要的小伙伴可以參考下2016-12-12
Python實現(xiàn)的求解最小公倍數(shù)算法示例
這篇文章主要介紹了Python實現(xiàn)的求解最小公倍數(shù)算法,涉及Python數(shù)值運算、判斷等相關操作技巧,需要的朋友可以參考下2018-05-05

