今天給大家分享一篇Pandas高級操作匯總~ 在數據分析和數據建模的過程中需要對數據進行清洗和整理等工作,有時需要對數據增刪字段。下面為大家介紹Pandas對數據的復雜查詢、數據類型轉換、數據排序、數據的修改、數據迭代以及函數的使用。
01、復雜查詢
實際業務需求往往需要按照一定的條件甚至復雜的組合條件來查詢數據,接下來為大家介紹如何發揮Pandas數據篩選的無限可能,隨心所欲地取用數據。
1、邏輯運算
# Q1成績大于36 df.Q1> 36 # Q1成績不小于60分,并且是C組成員 ~(df.Q1< 60) & (df['team'] == 'C')
2、邏輯篩選數據
切片([ ])、.loc[ ]和.iloc[ ]均支持上文所介紹的邏輯表達式。 以下是切片([ ])的邏輯篩選示例:
df[df['Q1']== 8] # Q1等于8 df[~(df['Q1']== 8)] # 不等于8 df[df.name== 'Ben'] # 姓名為Ben df[df.Q1> df.Q2]以下是.loc[ ]和.lic[ ]示例:
# 表達式與切片一致 df.loc[df['Q1']> 90, 'Q1':] # Q1大于90,只顯示Q1 df.loc[(df.Q1> 80) & (df.Q2 < 15)] # and關系 df.loc[(df.Q1> 90) | (df.Q2 < 90)] # or關系 df.loc[df['Q1']== 8] # 等于8 df.loc[df.Q1== 8] # 等于8 df.loc[df['Q1']> 90, 'Q1':] # Q1大于90,顯示Q1及其后所有列
3、函數篩選
# 查詢最大索引的值 df.Q1[lambdas: max(s.index)] # 值為21 # 計算最大值 max(df.Q1.index) # 99 df.Q1[df.index==99]
4、比較函數
# 以下相當于 df[df.Q1 == 60] df[df.Q1.eq(60)] df.ne() # 不等于 != df.le() # 小于等于 <= df.lt() # 小于 < df.ge() # 大于等于 >= df.gt() # 大于 >
5、查詢df.query()
df.query('Q1 > Q2 > 90') # 直接寫類型SQL where語句
還支持使用@符引入變量
# 支持傳入變量,如大于平均分40分的 a = df.Q1.mean() df.query('Q1>@a+40') df.query('Q1 > `Q2`+@a')
df.eval()與df.query()類似,也可以用于表達式篩選。
# df.eval()用法與df.query類似 df[df.eval("Q1 > 90 > Q3 >10")] df[df.eval("Q1 > `Q2`+@a")]
6、篩選df.filter()
df.filter(items=['Q1', 'Q2']) # 選擇兩列 df.filter(regex='Q', axis=1) # 列名包含Q的列 df.filter(regex='e$', axis=1) # 以e結尾的列 df.filter(regex='1$', axis=0) # 正則,索引名以1結尾 df.filter(like='2', axis=0) # 索引中有2的 # 索引中以2開頭、列名有Q的 df.filter(regex='^2',axis=0).filter(like='Q', axis=1)
7、按數據類型查詢
df.select_dtypes(include=['float64']) # 選擇float64型數據 df.select_dtypes(include='bool') df.select_dtypes(include=['number']) # 只取數字型 df.select_dtypes(exclude=['int'])#排除int類型 df.select_dtypes(exclude=['datetime64'])
02、數據類型轉換
在開始數據分析前,我們需要為數據分配好合適的類型,這樣才能夠高效地處理數據。不同的數據類型適用于不同的處理方法。
# 對所有字段指定統一類型 df = pd.DataFrame(data, dtype='float32') # 對每個字段分別指定 df = pd.read_excel(data, dtype={'team':'string', 'Q1': 'int32'})
1、推斷類型
# 自動轉換合適的數據類型 df.infer_objects()#推斷后的DataFrame df.infer_objects().dtypes
2、指定類型
# 按大體類型推定 m = ['1', 2, 3] s = pd.to_numeric(s) # 轉成數字 pd.to_datetime(m) # 轉成時間 pd.to_timedelta(m) # 轉成時間差 pd.to_datetime(m, errors='coerce') # 錯誤處理 pd.to_numeric(m, errors='ignore') pd.to_numeric(m errors='coerce').fillna(0) # 兜底填充 pd.to_datetime(df[['year', 'month', 'day']]) # 組合成日期
3、類型轉換astype()
df.Q1.astype('int32').dtypes # dtype('int32') df.astype({'Q1': 'int32','Q2':'int32'}).dtypes
4、轉為時間類型
t = pd.Series(['20200801', '20200802'])
03、數據排序
數據排序是指按一定的順序將數據重新排列,幫助使用者發現數據的變化趨勢,同時提供一定的業務線索,還具有對數據糾錯、分類等作用。
1、索引排序df.sort_index()
s.sort_index() # 升序排列 df.sort_index() # df也是按索引進行排序 df.team.sort_index()s.sort_index(ascending=False)# 降序排列 s.sort_index(inplace=True) # 排序后生效,改變原數據 # 索引重新0-(n-1)排,很有用,可以得到它的排序號 s.sort_index(ignore_index=True) s.sort_index(na_position='first') # 空值在前,另'last'表示空值在后 s.sort_index(level=1) # 如果多層,排一級 s.sort_index(level=1, sort_remaining=False) #這層不排 # 行索引排序,表頭排序 df.sort_index(axis=1) # 會把列按列名順序排列
2、數值排序sort_values()
df.Q1.sort_values() df.sort_values('Q4') df.sort_values(by=['team', 'name'],ascending=[True, False])
其他方法:
s.sort_values(ascending=False) # 降序 s.sort_values(inplace=True) # 修改生效 s.sort_values(na_position='first') # 空值在前 # df按指定字段排列 df.sort_values(by=['team']) df.sort_values('Q1') # 按多個字段,先排team,在同team內再看Q1 df.sort_values(by=['team', 'Q1']) # 全降序 df.sort_values(by=['team', 'Q1'], ascending=False) # 對應指定team升Q1降 df.sort_values(by=['team', 'Q1'],ascending=[True, False]) # 索引重新0-(n-1)排 df.sort_values('team', ignore_index=True)
3、混合排序
df.set_index('name', inplace=True) # 設置name為索引 df.index.names = ['s_name'] # 給索引起名 df.sort_values(by=['s_name', 'team']) # 排序
4、按值大小排序nsmallest()和nlargest()
s.nsmallest(3) # 最小的3個 s.nlargest(3) # 最大的3個 # 指定列 df.nlargest(3, 'Q1') df.nlargest(5,['Q1','Q2']) df.nsmallest(5, ['Q1', 'Q2'])
04、添加修改
數據的修改、增加和刪除在數據整理過程中時常發生。修改的情況一般是修改錯誤、格式轉換,數據的類型修改等。
1、修改數值
df.iloc[0,0] # 查詢值 # 'Liver' df.iloc[0,0] = 'Lily' # 修改值 df.iloc[0,0] # 查看結果 # 'Lily' # 將小于60分的成績修改為60 df[df.Q1 < 60] = 60 # 查看 df.Q1 # 生成一個長度為100的列表 v = [1, 3, 5, 7, 9] * 20
2、替換數據
s.replace(0, 5) # 將列數據中的0換為5 df.replace(0, 5) # 將數據中的所有0換為5 df.replace([0, 1, 2, 3], 4) # 將0~3全換成4 df.replace([0, 1, 2, 3], [4, 3, 2, 1]) # 對應修改 s.replace([1, 2], method='bfill') # 向下填充 df.replace({0: 10, 1: 100}) # 字典對應修改 df.replace({'Q1': 0, 'Q2': 5}, 100) # 將指定字段的指定值修改為100 df.replace({'Q1': {0: 100, 4: 400}}) # 將指定列里的指定值替換為另一個指定的值
3、填充空值
df.fillna(0) # 將空值全修改為0 # {'backfill', 'bfill', 'pad', 'ffill',None}, 默認為None df.fillna(method='ffill') # 將空值都修改為其前一個值 values = {'A': 0, 'B': 1, 'C': 2, 'D': 3} df.fillna(value=values)#為各列填充不同的值 df.fillna(value=values, limit=1) # 只替換第一個
4、修改索引名
df.rename(columns={'team':'class'})
常用方法如下:
df.rename(columns={"Q1":"a", "Q2": "b"}) # 對表頭進行修改 df.rename(index={0: "x", 1:"y", 2: "z"}) # 對索引進行修改 df.rename(index=str) # 對類型進行修改 df.rename(str.lower, axis='columns') # 傳索引類型 df.rename({1: 2, 2: 4}, axis='index') # 對索引名進行修改 s.rename_axis("animal") df.rename_axis("animal") # 默認是列索引 df.rename_axis("limbs",axis="columns") # 指定行索引 # 索引為多層索引時可以將type修改為class df.rename_axis(index={'type': 'class'}) # 可以用set_axis進行設置修改 s.set_axis(['a', 'b', 'c'], axis=0) df.set_axis(['I', 'II'], axis='columns') df.set_axis(['i', 'ii'], axis='columns',inplace=True)
5、增加列
df['foo'] = 100 # 增加一列foo,所有值都是100 df['foo'] = df.Q1 + df.Q2 # 新列為兩列相加 df['foo'] = df['Q1'] + df['Q2'] # 同上 # 把所有為數字的值加起來 df['total'] =df.select_dtypes(include=['int']).sum(1)df['total'] = df.loc[:,'Q1':'Q4'].apply(lambda x: sum(x), axis='columns') df.loc[:, 'Q10'] = '我是新來的' # 也可以 # 增加一列并賦值,不滿足條件的為NaN df.loc[df.num >= 60, '成績'] = '合格' df.loc[df.num < 60, '成績'] = '不合格'
6、插入列df.insert()
# 在第三列的位置上插入新列total列,值為每行的總成績 df.insert(2, 'total', df.sum(1))
7、指定列df.assign()
# 增加total列 df.assign(total=df.sum(1)) # 增加兩列 df.assign(total=df.sum(1), Q=100) df.assign(total=df.sum(1)).assign(Q=100) 其他使用示例: df.assign(Q5=[100]*100) # 新增加一列Q5 df = df.assign(Q5=[100]*100) # 賦值生效 df.assign(Q6=df.Q2/df.Q1) # 計算并增加Q6 df.assign(Q7=lambda d: d.Q1 * 9 / 5 + 32) # 使用lambda# 添加一列,值為表達式結果:True或False df.assign(tag=df.Q1>df.Q2) # 比較計算,True為1,False為0 df.assign(tag=(df.Q1>df.Q2).astype(int)) # 映射文案 df.assign(tag=(df.Q1>60).map({True:'及格',False:'不及格'})) # 增加多個 df.assign(Q8=lambda d: d.Q1*5, Q9=lambda d: d.Q8+1) # Q8沒有生效,不能直接用df.Q8
8、執行表達式df.eval()
# 傳入求總分表達式 df.eval('total=Q1+Q3+Q3+Q4')
其他方法:
df['C1'] = df.eval('Q2 + Q3') df.eval('C2 = Q2 + Q3') # 計算 a = df.Q1.mean()df.eval("C3 =`Q3`+@a") # 使用變量 df.eval("C3 = Q2 > (`Q3`+@a)") #加一個布爾值 df.eval('C4 = name + team', inplace=True) # 立即生效
9、增加行
# 新增索引為100的數據 df.loc[100]=['tom','A',88,88,88,88]
其他方法:
df.loc[101]={'Q1':88,'Q2':99} # 指定列,無數據列值為NaN df.loc[df.shape[0]+1] = {'Q1':88,'Q2':99} # 自動增加索引 df.loc[len(df)+1] = {'Q1':88,'Q2':99} # 批量操作,可以使用迭代 rows = [[1,2],[3,4],[5,6]] for row in rows: df.loc[len(df)] = row
10、追加合并
df = pd.DataFrame([[1, 2], [3, 4]],columns=list('AB')) df2 = pd.DataFrame([[5, 6], [7, 8]],columns=list('AB')) df.append(df2)
11、刪除
#刪除索引為3的數據 s.pop(3) # 93s s
12、刪除空值
df.dropna() # 一行中有一個缺失值就刪除 df.dropna(axis='columns') # 只保留全有值的列 df.dropna(how='all') # 行或列全沒值才刪除 df.dropna(thresh=2)#至少有兩個空值時才刪除 df.dropna(inplace=True) # 刪除并使替換生效
05、高級過濾
介紹幾個非常好用的復雜數據處理的數據過濾輸出方法。
1、df.where()
#數值大于70 df.where(df > 70)
2、np.where()
#小于60分為不及格 np.where(df>=60, '合格', '不合格')
3、df.mask()
#符合條件的為NaN df.mask(s > 80)
4、df.lookup()
# 行列相同數量,返回一個array df.lookup([1,3,4],['Q1','Q2','Q3'])#array([36,96,61]) df.lookup([1], ['Q1']) # array([36])
06、數據迭代
1、迭代Series
# 迭代指定的列 for i in df.name: print(i) # 迭代索引和指定的兩列 fori,n,qinzip(df.index,df.name,df.Q1): print(i, n, q)
2、df.iterrows()
# 迭代,使用name、Q1數據 forindex,rowindf.iterrows(): print(index, row['name'], row.Q1)
3、df.itertuples()
forrowindf.itertuples(): print(row)
4、df.items()
# Series取前三個 for label, ser in df.items(): print(label) print(ser[:3], end=' ')
5、按列迭代
# 直接對DataFrame迭代 for column in df: print(column)
07、函數應用
1、pipe()
應用在整個DataFrame或Series上。
# 對df多重應用多個函數 f(g(h(df), arg1=a), arg2=b, arg3=c) # 用pipe可以把它們連接起來 (df.pipe(h) .pipe(g, arg1=a) .pipe(f, arg2=b, arg3=c) )
2、apply()
應用在DataFrame的行或列中,默認為列。
#將name全部變為小寫 df.name.apply(lambda x: x.lower())
3、applymap()
應用在DataFrame的每個元素中。
# 計算數據的長度 def mylen(x): return len(str(x)) df.applymap(lambdax:mylen(x))#應用函數 df.applymap(mylen) # 效果同上
4、map()
應用在Series或DataFrame的一列的每個元素中。
df.team.map({'A':'一班','B':'二班','C':'三班','D':'四班',})#枚舉替換 df['name'].map(f)
5、agg()
# 每列的最大值 df.agg('max') # 將所有列聚合產生sum和min兩行 df.agg(['sum', 'min']) # 序列多個聚合 df.agg({'Q1' : ['sum', 'min'], 'Q2' : ['min','max']}) # 分組后聚合 df.groupby('team').agg('max') df.Q1.agg(['sum', 'mean'])
6、transform()
df.transform(lambdax:x*2)#應用匿名函數 df.transform([np.sqrt, np.exp]) # 調用多個函數
7、copy()
s = pd.Series([1, 2], index=["a","b"]) s_1 = s s_copy = s.copy() s_1 is s # True s_copy is s # False責任編輯:彭菁
-
數據
+關注
關注
8文章
6909瀏覽量
88850 -
函數
+關注
關注
3文章
4308瀏覽量
62447
原文標題:Pandas50 個高級操作,秀起來!
文章出處:【微信號:DBDevs,微信公眾號:數據分析與開發】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論