df['Physics'].notna().head()對DataFrame使用會返回布爾表但對於DataFrame我們更關心到底每列有多少缺失值
此外,可以通過第1章中介紹的info函數查看缺失信息
2、查看缺失值的所以在行以最後一列為例,挑出該列缺失值的行3、挑選出所有非缺失值列
使用all就是全部非缺失值,如果是any就是至少有一個不是缺失值三種缺失符號
1、np.nannp.nan是一個麻煩的東西,首先它不等與任何東西,甚至不等於自己。False
False
False
在用equals函數比較時,自動略過兩側全是np.nan的單元格,因此結果不會影響。True
其次,它在numpy中的類型為浮點,由此導致數據集讀入時,即使原來是整數的列,只要有缺失值就會變為浮點型。float
dtype('int64')
pd.Series([1,np.nan,3]).dtypedtype('float64')
此外,對於布爾類型的列表,如果是np.nan填充,那麼它的值會自動變為True而不是False。pd.Series([1,np.nan,3],dtype='bool')但當修改一個布爾列表時,會改變列表類型,而不是賦值為True。s = pd.Series([True,False],dtype='bool')s[1]=np.nans在所有的表格讀取後,無論列是存放什麼類型的數據,默認的缺失值全為np.nan類型。
因此整型列轉為浮點;而字符由於無法轉化為浮點,因此只能歸併為object類型('O'),原來是浮點型的則類型不變dtype('float64')
dtype('float64')
dtype('O')
2、NoneNone比前者稍微好些,至少它會等於自身True
它的布爾值為Falsepd.Series([None],dtype='bool')0 False
dtype: bool
修改布爾列表不會改變數據類型s = pd.Series([True,False],dtype='bool')s[0]=Nones0 False
1 False
dtype: bool
s = pd.Series([1,0],dtype='bool')s[0]=Nones0 False
1 False
dtype: bool
在傳入數值類型後,會自動變為np.nantype(pd.Series([1,None])[1])numpy.float64
只有當傳入object類型是保持不動,幾乎可以認為,除非人工命名None,它基本不會自動出現在Pandas中type(pd.Series([1,None],dtype='O')[1])NoneType
在使用equals函數時不會被略過,因此下面的情況下返回Falsepd.Series([None]).equals(pd.Series([np.nan]))False
3、NaTNaT是針對時間序列的缺失值,是Pandas的內置類型,可以完全看做時序版本的np.nan,與自己不等,且使用equals是也會被跳過s_time = pd.Series([pd.Timestamp('20120101')]*5)s_timepandas._libs.tslibs.nattype.NaTType
False
True
s = pd.Series([True,False],dtype='bool')s[1]=pd.NaTsNullable類型與NA符號
這是Pandas在1.0新版本中引入的重大改變,其目的就是為了(在若干版本後)解決之前出現的混亂局面,統一缺失值處理方法。"The goal of pd.NA is provide a 「missing」 indicator that can be used consistently across data types (instead of np.nan, None or pd.NaT depending on the data type)."——User Guide for Pandas v-1.0官方鼓勵用戶使用新的數據類型和缺失類型pd.NA1、Nullable整形對於該種類型而言,它與原來標記int上的符號區別在於首字母大寫:'Int's_original = pd.Series([1, 2], dtype="int64")s_originals_new = pd.Series([1, 2], dtype="Int64")s_new它的好處就在於,其中前面提到的三種缺失值都會被替換為統一的NA符號,且不改變數據類型。
s_original[1] = np.nans_original
2、Nullable布爾對於該種類型而言,作用與上面的類似,記號為booleans_original = pd.Series([1, 0], dtype="bool")s_originals_new = pd.Series([0, 1], dtype="boolean")s_news_original[0] = np.nans_original
s_original = pd.Series([1, 0], dtype="bool") #此處重新加一句是因為前面賦值改變了bool類型s_original[0] = Nones_original需要注意的是,含有pd.NA的布爾列表在1.0.2之前的版本作為索引時會報錯,這是一個之前的bug,現已經修復。s = pd.Series(['dog','cat'])s[s_new]3、string類型
該類型是1.0的一大創新,目的之一就是為了區分開原本含糊不清的object類型,這裡將簡要地提及string,因為它是第7章的主題內容。它本質上也屬於Nullable類型,因為並不會因為含有缺失而改變類型。s = pd.Series(['dog','cat'],dtype='string')s此外,和object類型的一點重要區別就在於,在調用字符方法後,string類型返回的是Nullable類型,object則會根據缺失類型和數據類型而改變。
s = pd.Series(["a", None, "b"], dtype="string")s.str.count('a')s2 = pd.Series(["a", None, "b"], dtype="object")s2.str.count("a")NA的特性
1、邏輯運算只需看該邏輯運算的結果是否依賴pd.NA的取值,如果依賴,則結果還是NA,如果不依賴,則直接計算結果。True
True
<NA>
False
<NA>
取值不明直接報錯2、算術運算和比較運算這裡只需記住除了下面兩類情況,其他結果都是NA即可1
1
其他情況:<NA>
<NA>
<NA>
<NA>
<NA>
<NA>
convert_dtypes方法這個函數的功能往往就是在讀取數據時,就把數據列轉為Nullable類型,是1.0的新函數。pd.read_csv('data/table_missing.csv').dtypespd.read_csv('data/table_missing.csv').convert_dtypes().dtypes缺失數據的運算與分組加號與乘號規則使用加法時,缺失值為0s = pd.Series([2,3,np.nan,4])s.sum()9.0
使用乘法時,缺失值為124.0
使用累計函數時,缺失值自動略過groupby方法中的缺失值
自動忽略為缺失值的組df_g = pd.DataFrame({'one':['A','B','C','D',np.nan],'two':np.random.randn(5)})df_gdf_g.groupby('one').groups填充與剔除
fillna方法1、值填充與前後向填充(分別與ffill方法和bfill方法等價)df['Physics'].fillna('missing').head()df['Physics'].fillna(method='ffill').head()df['Physics'].fillna(method='backfill').head()2、填充中的對齊特性
df_f = pd.DataFrame({'A':[1,3,np.nan],'B':[2,4,np.nan],'C':[3,5,np.nan]})df_f.fillna(df_f.mean())返回的結果中沒有C,根據對齊特點不會被填充
df_f.fillna(df_f.mean()[['A','B']])dropna方法
1、axis參數df_d = pd.DataFrame({'A':[np.nan,np.nan,np.nan],'B':[np.nan,3,2],'C':[3,2,1]})df_d2、how參數(可以選all或者any,表示全為缺失去除和存在缺失去除)df_d.dropna(axis=1,how='all')3、subset參數(即在某一組列範圍中搜索缺失值)¶df_d.dropna(axis=0,subset=['B','C'])插值
線性插值1、索引無關的線性插值默認狀態下,interpolate會對缺失的值進行線性插值s = pd.Series([1,10,15,-5,-2,np.nan,np.nan,28])s<matplotlib.axes._subplots.AxesSubplot at 0x7fe7df20af50>
此時的插值與索引無關s.index = np.sort(np.random.randint(50,300,8))s.interpolate()#值不變s.interpolate().plot()#後面三個點不是線性的(如果幾乎為線性函數,請重新運行上面的一個代碼塊,這是隨機性導致的)<matplotlib.axes._subplots.AxesSubplot at 0x7fe7dfc69890>
2、與索引有關的插值method中的index和time選項可以使插值線性地依賴索引,即插值為索引的線性函數s.interpolate(method='index').plot()#可以看到與上面的區別<matplotlib.axes._subplots.AxesSubplot at 0x7fe7dca0c4d0>
如果索引是時間,那麼可以按照時間長短插值,對於時間序列將在第9章詳細介紹s_t = pd.Series([0,np.nan,10] ,index=[pd.Timestamp('2012-05-01'),pd.Timestamp('2012-05-07'),pd.Timestamp('2012-06-03')])s_t<matplotlib.axes._subplots.AxesSubplot at 0x7fe7dc964850>
s_t.interpolate(method='time').plot()<matplotlib.axes._subplots.AxesSubplot at 0x7fe7dc8eda10>
高級插值方法此處的高級指的是與線性插值相比較,例如樣條插值、多項式插值、阿基瑪插值等(需要安裝Scipy)。關於這部分僅給出一個官方的例子,因為插值方法是數值分析的內容,而不是Pandas中的基本知識:ser = pd.Series(np.arange(1, 10.1, .25) ** 2 + np.random.randn(37))missing = np.array([4, 13, 14, 15, 16, 17, 18, 20, 29])ser[missing] = np.nanmethods = ['linear', 'quadratic', 'cubic']df = pd.DataFrame({m: ser.interpolate(method=m) for m in methods})df.plot()<matplotlib.axes._subplots.AxesSubplot at 0x7fe7dc86f810>
interpolate中的限制參數1、limit表示最多插入多少個s = pd.Series([1,np.nan,np.nan,np.nan,5])s.interpolate(limit=2)2、limit_direction表示插值方向,可選forward,backward,both,默認前向。s = pd.Series([np.nan,np.nan,1,np.nan,np.nan,np.nan,5,np.nan,np.nan,])s.interpolate(limit_direction='backward')3、limit_area表示插值區域,可選inside,outside,默認Nones = pd.Series([np.nan,np.nan,1,np.nan,np.nan,np.nan,5,np.nan,np.nan,])s.interpolate(limit_area='inside')s = pd.Series([np.nan,np.nan,1,np.nan,np.nan,np.nan,5,np.nan,np.nan,])s.interpolate(limit_area='outside')問題與練習問題
第一步,計算單列缺失值的數量,計算單列總樣本數
第二步,算出比例,得到一個列的布爾列表
第三步,利用這個布爾列表進行列索引或列刪除
df.loc[:,(df.isna().sum()/df.isna().count()<0.25).values]【問題二】 什麼是Nullable類型?請談談為什麼要引入這個設計?
Nullable類型是一種為了統一NaN,Null,NaT三類缺失值而誕生的新的類型。是在原來的數值、布爾、字符等類型的基礎上進行小改,優化了當出現缺失值情況時的應對。引入這個設計時為了更好的處理缺失值,統一缺失值處理方法
【問題三】 對於一份有缺失值的數據,可以採取哪些策略或方法深化對它的了解?可以查看缺失值出現的比例;
查看缺失值之間的關聯性;
查看總體的缺失信息;
根據缺失信息判斷是否為有效數據;
根據缺失信息清洗數據等等。
練習
【練習一】現有一份虛擬數據集,列類型分別為string/浮點/整型,請解決如下問題。
q1 = pd.read_csv('data/Missing_data_one.csv')q1.head() A B C0 not_NaN 0.922 4.01 not_NaN 0.700 NaN2 not_NaN 0.503 8.03 not_NaN 0.938 4.04 not_NaN 0.952 10.01.1 請以列類型讀入數據,並選出C為缺失值的行。
1.2 現需要將A中的部分單元轉為缺失值,單元格中的最小轉換概率為25%,且概率大小與所在行B列單元的值成正比
q1['A'] = pd.Series(list(zip(q1['A'].values,q1['B'].values))).apply(lambda x:x[0] if np.random.rand()>0.25*x[1]/q1['B'].min() else np.nan)【練習二】 現有一份缺失的數據集,記錄了36個人來自的地區、身高、體重、年齡和工資,解決如下問題:pd.read_csv('data/Missing_data_two.csv').head() 編號 地區 身高 體重 年齡 工資0 1 A 157.50 NaN 47.0 15905.01 2 B 202.00 91.80 25.0 NaN2 3 C 169.09 62.18 NaN NaN3 4 A 166.61 59.95 77.0 5434.04 5 B 185.19 NaN 62.0 4242.02.1 統計各列缺失的比例並選出在後三列中至少有兩個非缺失值的行
q2.isna().sum()/q2.shape[0]q2[q2.iloc[:,-3:].isna().sum(1)<=1].head()2.2 請結合身高列和地區列中的數據,對體重進行合理插值
q2_new = q2.copy()for area,group in q2.groupby('地區'): q2_new.loc[group.index,'體重'] = group[['身高','體重']].sort_values(by='身高').interpolate()['體重'] q2_new = q2_new.round(decimals=2)q2_new.head()本文電子版 後臺回復 缺失數據 獲取
「感謝你的在看,點讚,分享三連↓