<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          用Pandas對(duì)數(shù)據(jù)進(jìn)行復(fù)雜查詢,7步教你隨心所欲地取用數(shù)據(jù)

          共 3487字,需瀏覽 7分鐘

           ·

          2021-11-23 16:43

          ??????關(guān)注我,和老表一起學(xué)Python、云服務(wù)器


          導(dǎo)讀:在數(shù)據(jù)分析和數(shù)據(jù)建模的過程中需要對(duì)數(shù)據(jù)進(jìn)行清洗和整理等工作,有時(shí)需要對(duì)數(shù)據(jù)增刪字段。本文將介紹Pandas對(duì)數(shù)據(jù)的復(fù)雜查詢。

          實(shí)際業(yè)務(wù)需求往往需要按照一定的條件甚至復(fù)雜的組合條件來查詢數(shù)據(jù)。本文將介紹如何發(fā)揮Pandas數(shù)據(jù)篩選的無限可能,隨心所欲地取用數(shù)據(jù)。


          01
          邏輯運(yùn)算


          類似于Python的邏輯運(yùn)算,我們以DataFrame其中一列進(jìn)行邏輯計(jì)算,會(huì)產(chǎn)生一個(gè)對(duì)應(yīng)的由布爾值組成的Series,真假值由此位上的數(shù)據(jù)是否滿足邏輯表達(dá)式?jīng)Q定。例如下例中索引為0的數(shù)據(jù)值為89,大于36,所以最后值為True。
           1#?Q1成績(jī)大于36
          2df.Q1?>?36
          3'''
          40??????True
          51?????False
          62??????True
          73??????True
          84??????True
          9??????...??
          10
          1195?????True
          1296????False
          1397?????True
          1498????False
          1599????False
          16Name:?Q1,?Length:?100,?dtype:?bool
          17'''

          一個(gè)針對(duì)索引的邏輯表達(dá)式會(huì)產(chǎn)生一個(gè)array類型數(shù)組,該數(shù)組由布爾值組成。根據(jù)邏輯表達(dá)式,只有索引為1的值為True,其余全為False。

           1#?索引等于1
          2df.index?==?1
          3'''
          4array([False,??True,?False,?False,?False,?False,?False,?False,?False,
          5???????False,?False,?False,?False,?False,?False,?False,?False,?False,
          6???????False,?False,?False,?False,?False,?False,?False,?False,?False,
          7???????False,?False,?False,?False,?False,?False,?False,?False,?False,
          8???????False,?False,?False,?False,?False,?False,?False,?False,?False,
          9???????False,?False,?False,?False,?False,?False,?False,?False,?False,
          10???????False,?False,?False,?False,?False,?False,?False,?False,?False,
          11???????False,?False,?False,?False,?False,?False,?False,?False,?False,
          12???????False,?False,?False,?False,?False,?False,?False,?False,?False,
          13???????False,?False,?False,?False,?False,?False,?False,?False,?False,
          14???????False,?False,?False,?False,?False,?False,?False,?False,?False,
          15???????False])
          16'''

          再看一下關(guān)于DataFrame的邏輯運(yùn)算,判斷數(shù)值部分的所有值是否大于60,滿足表達(dá)式的值顯示為True,不滿足表達(dá)式的值顯示為False。

           1#?df.loc[:,'Q1':'Q4']部分只取數(shù)字部分,否則會(huì)因字符無大于運(yùn)算而報(bào)錯(cuò)
          2df.loc[:,'Q1':'Q4']?>?60
          3'''
          4???????Q1?????Q2?????Q3?????Q4
          50????True??False??False???True
          61???False??False??False??False
          72???False??False??False???True
          83????True???True???True???True
          94????True??False???True???True
          10..????...????...????...????...
          1195??False??False???True???True
          1296??False??False??False??False
          1397???True???True??False??False
          1498??False???True??False???True
          1599??False??False??False???True
          16[100?rows?x?4?columns]
          17'''

          除了邏輯運(yùn)算,Pandas還支持組合條件的Python位運(yùn)算:

           1#?Q1成績(jī)不小于60分,并且是C組成員
          2~(df.Q1?60
          )?&?(df['team']?==?'C')
          3'''
          40?????False
          51?????False
          62?????False
          73??????True
          84?????False
          9??????...??
          1095????False
          1196????False
          1297?????True
          1398????False
          1499????False
          15Length:?100,?dtype:?bool
          16'''


          02
          邏輯篩選數(shù)據(jù)


          切片([])、.loc[]和.iloc[]均支持上文所介紹的邏輯表達(dá)式。通過邏輯表達(dá)式進(jìn)行復(fù)雜條件的數(shù)據(jù)篩選時(shí)需要注意,表達(dá)式輸出的結(jié)果必須是一個(gè)布爾序列或者符合其格式要求的數(shù)據(jù)形式。例如,df.iloc[1+1]和df.iloc[lambda df: len(df)-1]計(jì)算出一個(gè)數(shù)值,符合索引的格式,df.iloc[df.index==8]返回的是一個(gè)布爾序列,df.iloc[df.index]返回的是一個(gè)索引,它們都是有效的表達(dá)式。

          以下是切片([])的一些邏輯篩選的示例:

          1df[df['Q1']?==?8]?#?Q1等于8
          2df[~(df['Q1']?==?8)]?#?不等于8
          3df[df.name?==?'Ben']?#?姓名為Ben
          4df[df.Q1?>?df.Q2]

          以下是.loc[]和.lic[]的一些示例:

          1#?表達(dá)式與切片一致
          2df.loc[df['Q1']?>?90,?'Q1':]??#?Q1大于90,只顯示Q1
          3df.loc[(df.Q1?>?80)?&?(df.Q2?#?and關(guān)系

          4df.loc[(df.Q1?>?90)?|?(df.Q2?#?or關(guān)系
          5df.loc[df['Q1']?==?8]?#?等于8
          6df.loc[df.Q1?==?8]?#?等于8
          7df.loc[df['Q1']?>?90,?'Q1':]?#?Q1大于90,顯示Q1及其后所有列

          需要注意的是在進(jìn)行或(|)、與(&)、非(~)運(yùn)算時(shí),各個(gè)獨(dú)立邏輯表達(dá)式需要用括號(hào)括起來。

          any和all對(duì)邏輯計(jì)算后的布爾序列再進(jìn)行判斷,序列中所有值都為True時(shí)all才返回True,序列中只要有一個(gè)值為True時(shí)any就返回True。它們還可以傳入axis參數(shù)的值,用于指定判斷的方向,與Pandas的axis參數(shù)整體約定一樣,默認(rèn)為0列方向,傳入1為行方向。利用這兩個(gè)方法,我們可以對(duì)整體數(shù)據(jù)進(jìn)行邏輯判斷,例如:

          1#?Q1、Q2成績(jī)?nèi)珵槌^80分的
          2df[(df.loc[:,['Q1','Q2']]?>?80).all(1)]
          3#?Q1、Q2成績(jī)至少有一個(gè)超過80分的
          4df[(df.loc[:,['Q1','Q2']]?>?80).any(1)]

          上例對(duì)兩個(gè)列整體先做邏輯計(jì)算得到一個(gè)兩列的布爾序列,然后用all和any在行方向上做邏輯計(jì)算。


          03
          函數(shù)篩選


          可以在表達(dá)式使用lambda函數(shù),默認(rèn)變量是其操作的對(duì)象。如果操作的對(duì)象是一個(gè)DataFrame,那么變量就是這個(gè)DataFrame;如果是一個(gè)Series,那么就是這個(gè)Series。可以看以下例子,s就是指df.Q1這個(gè)Series:
          1#?查詢最大索引的值
          2df.Q1[lambda?s:?max(s.index)]?#?值為21
          3#?計(jì)算最大值
          4max(df.Q1.index)?#?99
          5df.Q1[df.index==99]
          6'''
          799????21
          8Name:?Q1,?dtype:?int64
          9'''

          下面是一些示例:

          1df[lambda?df:?df['Q1']?==?8]?#?Q1為8的
          2df.loc[lambda?df:?df.Q1?==?8,?'Q1':'Q2']?#?Q1為8的,顯示?Q1、Q2
          3df.loc[:,?lambda?df:?df.columns.str.len()==4]?#?由真假值組成的序列
          4df.loc[:,?lambda?df:?[i?for?i?in?df.columns?if?'Q'?in?i]]?#?列名列表
          5df.iloc[:3,?lambda?df:?df.columns.str.len()==2]?#?由真假值組成的序列


          04
          比較函數(shù)

          Pandas提供了一些比較函數(shù),使我們可以將邏輯表達(dá)式替換為函數(shù)形式。

          1#?以下相當(dāng)于?df[df.Q1?==?60]
          2df[df.Q1.eq(60)]
          3'''
          4?????name?team??Q1??Q2??Q3??Q4
          520??Lucas????A??60??41??77??62
          6'''

          除了.eq(),還有:

          1df.ne()?#?不等于?!=
          2df.le()?#?小于等于?<=
          3df.lt()?#?小于?<
          4df.ge()?#?大于等于?>=
          5df.gt()?#?大于?>

          使用示例如下:

          1df[df.Q1.ne(89)]?#?Q1不等于89
          2df.loc[df.Q1.gt(90)?&?df.Q2.lt(90)]?#?and關(guān)系,Q1>90,Q2<90

          這些函數(shù)可以傳入一個(gè)定值、數(shù)列、布爾序列、Series或DataFrame,來與原數(shù)據(jù)比較。

          另外還有一個(gè). isin()函數(shù),用于判斷數(shù)據(jù)是否包含指定內(nèi)容。可以傳入一個(gè)列表,原數(shù)據(jù)只需要滿足其中一個(gè)存在即可;也可以傳入一個(gè)字典,鍵為列名,值為需要匹配的值,以實(shí)現(xiàn)按列個(gè)性化匹配存在值。

          1#?isin
          2df[df.team.isin(['A','B'])]?#?包含A、B兩組的
          3df[df.isin({'team':?['C',?'D'],?'Q1':[36,93]})]?#?復(fù)雜查詢,其他值為NaN


          05
          查詢df.query()

          df.query(expr)使用布爾表達(dá)式查詢DataFrame的列,表達(dá)式是一個(gè)字符串,類似于SQL中的where從句,不過它相當(dāng)靈活。

          1df.query('Q1?>?Q2?>?90')?#?直接寫類型SQL?where語句
          2df.query('Q1?+?Q2?>?180')
          3df.query('Q1?==?Q2')
          4df.query('(Q1<50)?&?(Q2>40)?and?(Q3>90)')
          5df.query('Q1?>?Q2?>?Q3?>?Q4')
          6df.query('team?!=?"C"')
          7df.query('team?not?in?("E","A","B")')
          8#?對(duì)于名稱中帶有空格的列,可以使用反引號(hào)引起來
          9df.query('B?==?`team?name`')

          還支持使用@符引入變量:

          1#?支持傳入變量,如大于平均分40分的
          2a?=?df.Q1.mean()
          3df.query('Q1?>?@a+40')
          4df.query('Q1?>?`Q2`+@a')

          df.eval()與df.query()類似,也可以用于表達(dá)式篩選:

          1#?df.eval()用法與df.query類似
          2df[df.eval("Q1?>?90?>?Q3?>?10")]
          3df[df.eval("Q1?>?`Q2`+@a")]


          06
          篩選df.filter()

          df.filter()可以對(duì)行名和列名進(jìn)行篩選,支持模糊匹配、正則表達(dá)式。

          1df.filter(items=['Q1',?'Q2'])?#?選擇兩列
          2df.filter(regex='Q',?axis=1)?#?列名包含Q的列
          3df.filter(regex='e$',?axis=1)?#?以e結(jié)尾的列
          4df.filter(regex='1$',?axis=0)?#?正則,索引名以1結(jié)尾
          5df.filter(like='2',?axis=0)?#?索引中有2的
          6#?索引中以2開頭、列名有Q的
          7df.filter(regex='^2',?axis=0).filter(like='Q',?axis=1)


          07
          按數(shù)據(jù)類型查詢

          Pandas提供了一個(gè)按列數(shù)據(jù)類型篩選的功能df.select_dtypes(include=None, exclude=None),它可以指定包含和不包含的數(shù)據(jù)類型,如果只有一個(gè)類型,傳入字符;如果有多個(gè)類型,傳入列表。

          1df.select_dtypes(include=['float64'])?#?選擇float64型數(shù)據(jù)
          2df.select_dtypes(include='bool')
          3df.select_dtypes(include=['number'])?#?只取數(shù)字型
          4df.select_dtypes(exclude=['int'])?#?排除int類型
          5df.select_dtypes(exclude=['datetime64'])

          如果沒有滿足條件的數(shù)據(jù),會(huì)返回一個(gè)僅有索引的DataFrame。


          08
          小結(jié)

          本文介紹了如何實(shí)現(xiàn)復(fù)雜邏輯的數(shù)據(jù)查詢需求,復(fù)雜的數(shù)據(jù)查詢功能是Pandas的殺手锏,這些功能Excel實(shí)現(xiàn)起來會(huì)比較困難,有些甚至無法實(shí)現(xiàn),這正是Pandas的優(yōu)勢(shì)所在。

          - END -


          本文摘編于《深入淺出Pandas:利用Python進(jìn)行數(shù)據(jù)處理與分析》,經(jīng)出版方授權(quán)發(fā)布。



          推薦語:這是一本全面覆蓋了Pandas使用者的普遍需求和痛點(diǎn)的著作,基于實(shí)用、易學(xué)的原則,從功能、使用、原理等多個(gè)維度對(duì)Pandas做了全方位的詳細(xì)講解,既是初學(xué)者系統(tǒng)學(xué)習(xí)Pandas難得的入門書,又是有經(jīng)驗(yàn)的Python工程師案頭必不可少的查詢手冊(cè)。?


          關(guān)于作者:李慶輝,數(shù)據(jù)產(chǎn)品專家,某電商公司數(shù)據(jù)產(chǎn)品團(tuán)隊(duì)負(fù)責(zé)人,擅長(zhǎng)通過數(shù)據(jù)治理、數(shù)據(jù)分析、數(shù)據(jù)化運(yùn)營(yíng)提升公司的數(shù)據(jù)應(yīng)用水平。?

          如何找到我:

          近期優(yōu)質(zhì)文章:

          Linux里的寶塔,真正的寶塔!詳細(xì)教程

          10行代碼!

          擁有一臺(tái)服務(wù)器后,我竟然這么酷?

          學(xué)習(xí)更多:
          整理了我開始分享學(xué)習(xí)筆記到現(xiàn)在超過250篇優(yōu)質(zhì)文章,涵蓋數(shù)據(jù)分析、爬蟲、機(jī)器學(xué)習(xí)等方面,別再說不知道該從哪開始,實(shí)戰(zhàn)哪里找了
          點(diǎn)贊”就是對(duì)博主最大的支持?
          瀏覽 56
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  www.三级在线 | 天天操天天天 | 国产色哟哟在线观看 | 逼逼插逼逼| 欧洲激情第一页 |