Pandas50個高階操作,秀起來!

數據分析那些事
18 min readMay 31, 2023

--

在資料分析和資料建模的過程中需要對資料進行清洗和整理等工作,有時需要對資料增刪欄位。今天給大家分享一篇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='²',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)
# 迭代索引和指定的兩列
for i,n,q in zip(df.index, df.name,df.Q1):
print(i, n, q)

2、df.iterrows()

# 迭代,使用name、Q1資料
for index, row in df.iterrows():
print(index, row['name'], row.Q1)

3、df.itertuples()

for row in df.itertuples():
print(row)

4、df.items()

# Series取前三個
for label, ser in df.items():
print(label)
print(ser[:3], end='\n\n')

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(lambda x: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(lambda x: 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

文章來源:可以叫我才哥
原文連結:https://mp.weixin.qq.com/s/f0ACnMhauO0oZScnihcmkA

※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※

我是「數據分析那些事」。常年分享數據分析乾貨,不定期分享好用的職場技能工具。各位也可以關注我的Facebook,按讚我的臉書並私訊「10」,送你十週入門數據分析電子書唷!期待你與我互動起來~

文章推薦

餅圖變形記,肝了3000字,收藏就是學會!

MySQL必須掌握4種語言!

太實用了!4種方法教你輕鬆製作互動式儀表板!

跟資料打交道的人都得會的這8種資料模型,滿足工作中95%的需求

妙呀!一行Python程式碼

回顧十週入門數據分析系列文:

關注數據君的臉書:

我是「數據分析那些事」。常年分享數據分析乾貨,不定期分享好用的職場技能工具。按贊我的臉書,會有豐富資料包贈送唷!

--

--

數據分析那些事
數據分析那些事

Written by 數據分析那些事

這是一個專注於數據分析職場的內容部落格,聚焦一批數據分析愛好者,在這裡,我會分享數據分析相關知識點推送、(工具/書籍)等推薦、職場心得、熱點資訊剖析以及資源大盤點,希望同樣熱愛數據的我們一同進步! 臉書會有更多互動喔:https://www.facebook.com/shujvfenxi/

No responses yet