Pandas中選擇數(shù)據(jù)的子集 第二部分

在Pandas中選擇數(shù)據(jù)的子集 第二部分
第二部分:布爾索引
這是關(guān)于如何從pandas數(shù)據(jù)框架或系列中選擇數(shù)據(jù)子集的四部分系列的第二部分连霉。Pandas為子集的選擇提供了各種各樣的選項(xiàng)寞蚌,這就需要有多篇文章拼余。這個(gè)系列被分成以下四個(gè)主題。

用[]兆衅、.loc和.iloc選擇
布爾索引
指派數(shù)據(jù)子集
如何不選擇數(shù)據(jù)子集
了解更多
Master Data Analysis with Python是一本非常全面的書床未,有80多個(gè)章節(jié)和500個(gè)練習(xí),可以幫助你成為一個(gè)專家脑蠕。

第1部分與第2部分子集選擇
本系列的第一部分涵蓋了用[]、.loc和.iloc進(jìn)行子集選擇竭宰。這三個(gè)索引器都使用行/列標(biāo)簽或其整數(shù)位置來進(jìn)行選擇空郊。在選擇過程中完全不使用系列/數(shù)據(jù)框架的實(shí)際數(shù)據(jù)份招。

在本系列的第二部分切揭,關(guān)于布爾索引狞甚,我們將根據(jù)系列/數(shù)據(jù)框架中數(shù)據(jù)的實(shí)際值,而不是根據(jù)它們的行/列標(biāo)簽或整數(shù)位置來選擇數(shù)據(jù)子集廓旬。

關(guān)于布爾選擇的文檔
在學(xué)習(xí)布爾選擇時(shí)哼审,除了本教程外,我一直建議閱讀官方文檔孕豹。文檔中使用了更多帶有假數(shù)據(jù)的正式例子涩盾,但仍然是一個(gè)很好的資源。

文檔中使用了布爾索引這個(gè)詞励背,但你也會看到布爾選擇春霍。

pandas文檔中的布爾索引

Stack Overflow數(shù)據(jù)
我們在本教程中使用的數(shù)據(jù)來自Stack Overflow的數(shù)據(jù)資源管理器,這是一個(gè)神奇的工具叶眉,可以從網(wǎng)站上收集大量的數(shù)據(jù)址儒。你必須知道SQL,才能使用數(shù)據(jù)探索器衅疙。數(shù)據(jù)資源管理器允許你保存查詢莲趣。看一看我用來收集數(shù)據(jù)的查詢饱溢。

下表包含了在 stack overflow 上被標(biāo)記為 pandas 的每個(gè)問題的數(shù)據(jù)喧伞。

第一個(gè)問題是2011年3月30日提出的。從那時(shí)起绩郎,截至2017年12月2日潘鲫,已經(jīng)有超過56,000個(gè)問題被添加。

import pandas as pd
import numpy as np
so = pd.read_csv('././data/stackoverflow_qa.csv')
so.head()

用淺顯的英語提出簡單的問題
在我們討論布爾索引的技術(shù)定義之前肋杖,讓我們看看它能回答的問題類型的一些例子溉仑。

找到所有在2014年之前創(chuàng)建的問題
找到所有得分超過50分的問題
查找所有得分在50至100之間的問題
查找所有由斯科特-波士頓回答的問題
查找所有由以下5位用戶回答的問題
查找所有在2014年3月至2014年10月期間創(chuàng)建的、由Unutbu回答且得分低于5分的問題兽愤。
查找所有得分在5-10之間或?yàn)g覽量大于10,000的問題
找到所有未被斯科特-波士頓回答的問題
你也會看到這樣的例子被稱為查詢彼念。

所有的查詢都有標(biāo)準(zhǔn)
上述每個(gè)查詢都有一個(gè)嚴(yán)格的邏輯標(biāo)準(zhǔn),必須一次檢查一行浅萧。

保留或丟棄整行數(shù)據(jù)
如果你要手動回答上述查詢逐沙,你需要掃描每一行,并確定該行作為一個(gè)整體是否符合標(biāo)準(zhǔn)洼畅。如果該行符合標(biāo)準(zhǔn)吩案,那么它就會被保留,如果不符合帝簇,那么它就會被丟棄徘郭。

每一行都會有一個(gè)與之相關(guān)的真或假的值
當(dāng)你執(zhí)行布爾索引時(shí)靠益,DataFrame的每一行(或一個(gè)系列的值)將有一個(gè)True或False的值與之相關(guān),這取決于它是否符合標(biāo)準(zhǔn)残揉。真/假值被稱為布爾值胧后。文檔中稱整個(gè)過程為布爾式索引。

因?yàn)槲覀兪怯貌紶栔祦磉x擇數(shù)據(jù)抱环,所以有時(shí)被稱為布爾選擇壳快。從本質(zhì)上講,我們是用布爾值來選擇數(shù)據(jù)的子集镇草。

使用[ ]和.loc進(jìn)行布爾選擇
我們將使用第一部分中相同的三個(gè)索引器眶痰,[]和.loc來完成我們的布爾式選擇。我們將通過在這些索引器中放置一個(gè)布爾序列來實(shí)現(xiàn)梯啤。這個(gè)序列的行數(shù)/值與它正在進(jìn)行選擇的DataFrame/Series的行數(shù)/值相同竖伯。

.iloc索引器可以與布爾選擇一起工作,但幾乎從未被使用因宇。最后有一個(gè)小節(jié)會說明為什么它是不必要的七婴。

暫時(shí)集中在[ ]上
為了簡化事情,我們將只使用大括號羽嫡,[]本姥,我把它稱為第一部分中的索引操作符而已。我們將在稍后得到其他的索引器杭棵。

用Python進(jìn)行主數(shù)據(jù)分析
Master Data Analysis with Python是一個(gè)非常全面的課程婚惫,它將幫助你學(xué)習(xí)pandas來做數(shù)據(jù)分析。

我相信這是學(xué)習(xí)如何用pandas進(jìn)行數(shù)據(jù)分析的最佳資源魂爪,如果你不滿意先舷,我提供30天100%退款保證。

使用一個(gè)小的DataFrame來開始
在我們做第一個(gè)布爾選擇之前滓侍,讓我們簡化一下蒋川,使用堆棧溢出數(shù)據(jù)的前五行作為我們的起始DataFrame。

so_head = so.head()
so_head

手動創(chuàng)建一個(gè)布爾值的列表
對于我們的第一個(gè)布爾值選擇撩笆,我們不會回答任何有趣的 "英語 "查詢捺球,而只是用布爾值列表來選擇行。

例如夕冲,讓我們通過創(chuàng)建以下列表來選擇第一和第三行氮兵。

criteria = [True, False, True, False, False)

我們可以把這個(gè)布爾運(yùn)算的列表傳遞給索引運(yùn)算符,完成我們的選擇歹鱼。

so_head[criteria]

等一下......[ ]不是只用于列選擇嗎泣栈?
對于DataFrame來說,僅僅是索引操作符的主要目的是通過使用一個(gè)字符串或一個(gè)字符串列表來選擇一個(gè)或多個(gè)列。現(xiàn)在南片,突然間掺涛,這個(gè)例子顯示整個(gè)行是用布爾值選擇的。這就是讓pandas疼进,不幸的是薪缆,成為使用起來最混亂的庫之一。

操作符重載
只有索引操作符是重載的颠悬。這意味著矮燎,根據(jù)輸入的不同定血,pandas會做一些完全不同的事情赔癌。下面是你傳遞給僅僅是索引操作符的不同對象的規(guī)則。

字符串--返回一個(gè)列作為一個(gè)系列
字符串列表--將所有這些列作為一個(gè)DataFrame返回
一個(gè)片斷--選擇行(可以同時(shí)做標(biāo)簽和整數(shù)的位置--令人困惑@焦怠)灾票。
一個(gè)布爾運(yùn)算的序列--選擇所有為真的行
綜上所述,主要是索引操作符選擇列茫虽,但如果你傳遞給它一個(gè)布爾運(yùn)算序列刊苍,它將選擇所有為 "真 "的行。

你說的 "序列 "是什么意思濒析?
我一直用布爾運(yùn)算序列這個(gè)詞來指代真/假值正什。從技術(shù)上講,最常見的內(nèi)置 Python 序列類型是列表和圖元号杏。除了列表之外婴氮,你最常使用的是 pandas 系列作為你的布爾運(yùn)算 "序列"。

讓我們手動創(chuàng)建一個(gè)布爾序列來選擇 so_head 的最后三行盾致。

s = pd.Series([False, False, True, True, True])
s
0    False
1    False
2     True
3     True
4     True
dtype: bool
so_head[s]

手工創(chuàng)建布爾型系列時(shí)要注意
上面的例子之所以有效主经,是因?yàn)椴紶栂盗泻蛃o_head的索引完全相同。讓我們輸出它們庭惜,以便你能清楚地看到這一點(diǎn)罩驻。

s.index
RangeIndex(start=0, stop=5, step=1)
so_head.index
RangeIndex(start=0, stop=5, step=1)

當(dāng)索引不對齊時(shí),布爾型選擇失敗
當(dāng)你使用一個(gè)布爾系列來做布爾選擇時(shí)护赊,兩個(gè)對象的索引必須完全相同惠遏。讓我們創(chuàng)建一個(gè)稍微不同的系列,其索引與它所索引的DataFrame不同骏啰。

s = pd.Series([False, False, True, True, True], index=[2, 3, 4, 5, 6])
s
2    False
3    False
4     True
5     True
6     True
dtype: bool
so_head[s]

IndexingError: 作為索引器提供的布爾系列無法對齊(布爾系列的索引和被索引對象的索引不匹配
IndexingError: 無法對齊的布爾系列!
如果布爾系列和你正在進(jìn)行布爾選擇的對象的索引不完全匹配节吮,你會得到上述錯(cuò)誤。這就是為什么你幾乎不會像這樣手工創(chuàng)建布爾系列的原因之一器一,你會在下面看到课锌。

同時(shí)使用NumPy數(shù)組
你也可以使用NumPy數(shù)組來做布爾選擇。NumPy數(shù)組沒有索引,所以你不會得到上面的錯(cuò)誤渺贤,但是你的數(shù)組需要和你要做布爾選擇的對象的長度完全相同雏胃。

a = np.array([True, False, False, False])
so_head[a]

不要手工創(chuàng)建布爾系列
你可能永遠(yuǎn)不會像上面那樣手工創(chuàng)建一個(gè)布爾系列。相反志鞍,你會根據(jù)你的數(shù)據(jù)值來產(chǎn)生它們瞭亮。

使用比較運(yùn)算符來創(chuàng)建布爾型系列
創(chuàng)建布爾系列的主要方法是使用六個(gè)比較運(yùn)算符中的一個(gè)。

<
<=

=
==
!=

對單列數(shù)據(jù)使用比較運(yùn)算符
你幾乎總是在單列或系列的數(shù)據(jù)上使用比較運(yùn)算符固棚。例如统翩,讓我們從分?jǐn)?shù)列創(chuàng)建一個(gè)布爾系列。讓我們來確定分?jǐn)?shù)是否至少為10此洲。

我們選擇分?jǐn)?shù)列厂汗,然后測試每個(gè)值是否大于或等于10的條件。注意呜师,這個(gè)操作被應(yīng)用于系列中的每個(gè)值娶桦。一個(gè)布爾型系列被返回。

criteria = so['score'] >= 10
criteria.head(10)
0    False
1    False
2    False
3    False
4    False
5    False
6     True
7     True
8     True
9    False
Name: score, dtype: bool

最后做一個(gè)布爾型選擇
現(xiàn)在我們在變量criteria中存儲了我們的布爾系列汁汗,我們可以將其傳遞給索引操作符衷畦,以便只選擇得分至少為10的行。

在本教程的其余部分知牌,我們將使用整個(gè)so數(shù)據(jù)框架祈争。

so_score_10_or_more = so[criteria]
so_score_10_or_more.head()

有多少行的分?jǐn)?shù)至少為10分
僅僅通過查看結(jié)果DataFrame的頭部,我們不知道有多少行通過了我們的標(biāo)準(zhǔn)角寸。讓我們輸出我們的原始數(shù)據(jù)框架和結(jié)果數(shù)據(jù)框架的形狀菩混。

 so.shape
(56398, 12)
 so_score_10_or_more.shape
(1505, 12)

只有大約3%的問題得到10分或更多。

一行中的布爾選擇
通常袭厂,你會看到布爾選擇發(fā)生在一行代碼中墨吓,而不是我們上面使用的多行代碼。如果下面的內(nèi)容讓你感到困惑纹磺,那么我建議將你的布爾系列存儲到一個(gè)變量中帖烘,就像我在上面對標(biāo)準(zhǔn)所做的那樣。

也可以把創(chuàng)建布爾系列的操作放在索引操作符里面橄杨,就像這樣秘症。

 so[so['score'] >= 10].head()

單一條件表達(dá)式
我們的第一個(gè)例子測試了一個(gè)單一條件(分?jǐn)?shù)是否為10或更多)。讓我們來測試一個(gè)不同的單一條件式矫,尋找所有由Scott Boston回答的問題乡摹。ans_name變量保存了發(fā)布接受的問題答案的人的顯示名稱。

我們使用==運(yùn)算符來測試是否相等采转,并再次將這個(gè)結(jié)果存儲到變量criteria中聪廉。同樣瞬痘,我們把這個(gè)變量傳給索引運(yùn)算符,這樣就完成了我們的選擇板熊。

第一步--創(chuàng)建布爾系列

 criteria = so['ans_name'] == 'Scott Boston' 框全。

第2步--做布爾型選擇

 so[criteria].head()

多條件表達(dá)式
到目前為止,我們的兩個(gè)布爾選擇都涉及到一個(gè)單一的條件干签。當(dāng)然津辩,你可以有你想要的多個(gè)條件。要做到這一點(diǎn)容劳,你需要使用三個(gè)邏輯運(yùn)算符and喘沿、or和not來組合你的布爾表達(dá)式。

使用&, | , ~
盡管Python使用了and, or, and not的語法竭贩,但是當(dāng)用pandas測試多個(gè)條件時(shí)蚜印,這些語法將不起作用。

你必須在 pandas 中使用以下運(yùn)算符娶视。

& 用于和
| 表示或
~ 表示不

我們的第一個(gè)多條件表達(dá)式
讓我們找到所有得分至少為5分并且由Scott Boston回答的問題晒哄。首先,我們將創(chuàng)建兩個(gè)單獨(dú)的變量來保存每個(gè)條件肪获。

 criteria_1 = so['score'] >= 5
 criteria_2 = so['ans_name'] == 'Scott Boston'。

然后柒傻,我們將使用和運(yùn)算符孝赫,即安培號&,來合并它們

 criteria_all = criteria_1 & criteria_2

現(xiàn)在我們可以把這個(gè)最后的標(biāo)準(zhǔn)傳遞給索引運(yùn)算符

 so[critical_all]

如果你喜歡這篇文章红符,可以考慮購買 "全能通行證"青柄,它包括我所有當(dāng)前和未來的材料,價(jià)格低廉预侯。

一行中的多個(gè)條件
可以將整個(gè)表達(dá)式合并成一行致开。許多pandas用戶喜歡這樣做,其他人則討厭這樣做萎馅。無論如何双戳,知道如何這樣做是個(gè)好主意,因?yàn)槟憧隙〞龅竭@種情況糜芳。

使用小括號來分隔條件
你必須將每個(gè)條件封裝在一組小括號中飒货,才能使其發(fā)揮作用。

每個(gè)條件將像這樣分開峭竣。

 (so['score'] >= 5) & (so['ans_name'] == 'Scott Boston')

然后塘辅,我們可以把這個(gè)表達(dá)式丟在只有索引操作符的里面

與之前的結(jié)果相同

 so[(so['score'] >= 5) & (so['ans_name'] == 'Scott Boston')] 。

使用一個(gè)或條件
讓我們找到所有分?jǐn)?shù)至少為100分或至少有10個(gè)答案的問題皆撩。

對于or條件扣墩,我們使用管道|。

 so[(so['score'] >= 100) | (so['answerercount'] >= 10)] .head()

用not操作符反轉(zhuǎn)一個(gè)條件
斜體字~代表not操作符,可以反轉(zhuǎn)一個(gè)條件呻惕。例如盘榨,如果我們想要所有分?jǐn)?shù)大于100的問題,我們可以這樣做蟆融。

 so[~(so['score'] <= 100)].head()

注意草巡,在 "分?jǐn)?shù)小于等于100 "的條件周圍有圓括號。我們必須在這里使用小括號型酥,否則操作就不能正確進(jìn)行山憨。

當(dāng)然,這個(gè)微不足道的例子不需要not運(yùn)算符弥喉,可以用大于運(yùn)算符來代替郁竟,但這很容易驗(yàn)證。

讓我們回過頭來看一個(gè)例子由境,把分?jǐn)?shù)至少為100或答案數(shù)至少為10的條件反過來棚亩。要做到這一點(diǎn),我們必須用小括號把我們的整個(gè)表達(dá)式包起來虏杰,像這樣讥蟆。

 ~((so['score'] >= 100) | (so['answerercount'] >= 10))

每個(gè)內(nèi)部表達(dá)式周圍也有一組小括號。

復(fù)雜的條件
我們可以建立極其復(fù)雜的條件來選擇符合特定條件的DataFrame的行纺阔。例如瘸彤,我們可以選擇Scott Boston回答的所有問題,得分在5分或以上笛钝,或者Ted Petrou回答的問題质况,答案數(shù)在5分或以上。

對于多個(gè)條件玻靡,最好將邏輯分成多個(gè)步驟结榄。


 criteria_1 = (so['score'] >= 5) & (so['ans_name'] == 'Scott Boston')
 criteria_2 = (so['answerercount'] >= 5) & (so['ans_name'] == 'Ted Petrou')
 criteria_all = criteria_1 | criteria_2
 so[candal_all]

單一列中的大量或條件 - 使用isin
偶爾,我們會想在一列中測試多個(gè)值的相等性囤捻。這在字符串列中是最常見的臼朗。例如,假設(shè)我們想找到Scott Boston, Ted Petrou, MaxU和unutbu回答的所有問題最蕾。

做到這一點(diǎn)的一個(gè)方法是用四個(gè)或條件依溯。

criteria = (((so['ans_name'] == 'Scott Boston') |) 
                (so['ans_name'] == 'Ted Petrou') | | 
                (so['ans_name'] == 'MaxU') | (so['ans_name'] == 'MaxU') 
                (so['ans_name'] == 'unutbu')

一個(gè)更簡單的方法是使用系列方法isin。把你要檢查的所有項(xiàng)目的列表傳給它瘟则,以確定是否相等黎炉。

 criteria = so['ans_name'].isin(['Scott Boston', 'Ted Petrou',            
                                    'MaxU', 'unutbu'])
criteria.head()
0    False
1    False
2    False
3    False
4    False
Name: ans_name, dtype: bool
 so[criteria].head()

練習(xí)Python - 對Python的全面介紹(200多頁,100多道練習(xí)題)醋拧。
Master Data Analysis with Python - 最全面的學(xué)習(xí)pandas的課程慷嗜。(800多頁淀弹,350多個(gè)練習(xí))
用Python掌握機(jī)器學(xué)習(xí) - 深入研究用scikit-learn進(jìn)行機(jī)器學(xué)習(xí),不斷更新以展示最新和最偉大的工具庆械。(300多頁)

將isin與其他標(biāo)準(zhǔn)相結(jié)合
你可以像使用邏輯運(yùn)算符一樣薇溃,使用isin方法產(chǎn)生的布爾系列。例如缭乘,如果我們想找到上面這些人回答的所有問題沐序,并且分?jǐn)?shù)大于30分,我們可以做以下工作堕绩。

criteria_1 = so['ans_name'].isin(['Scott Boston', 'Ted Petrou', 
                                      'MaxU', 'unutbu'])
criteria_2 = so['score'] > 30
criteria_all = criteria_1 & criteria_2
 so[critical_all].tail()

使用isnull來查找有缺失值的記錄
isnull方法返回一個(gè)布爾系列策幼,其中True表示一個(gè)缺失的值。例如奴紧,沒有接受的答案的問題特姐,其ans_name的值是缺失的。讓我們在這一列上調(diào)用isnull黍氮。

no_answer = so['ans_name'].isnull()
no_answer.head(6)
0    False
1    False
2    False
3    False
4    False
5     True
Name: ans_name, dtype: bool

這只是另一個(gè)布爾系列唐含,我們可以把它傳遞給僅僅是索引運(yùn)算符。

so[no_answer].head()

isnull的一個(gè)別名是isna方法沫浆。別名意味著它是相同的方法捷枯,只是名字不同而已。

在一個(gè)系列上的布爾選擇
到目前為止件缸,所有的例子都是發(fā)生在So DataFrame上的铜靶。在系列上進(jìn)行布爾選擇的情況幾乎相同。由于只有一個(gè)維度的數(shù)據(jù)他炊,你的查詢通常會比較簡單。

首先已艰,讓我們選擇一個(gè)單列的數(shù)據(jù)作為系列痊末,比如commentcount列。

s = so['commentcount']
s.head()
0    4
1    6
2    0
3    0
4    0
Name: commentcount, dtype: int64

讓我們測試一下大于10的評論數(shù)

criteria = s > 10
criteria.head()
0    False
1    False
2    False
3    False
4    False
Name: commentcount, dtype: bool

注意哩掺,這里沒有列的選擇凿叠,因?yàn)槲覀円呀?jīng)只剩下一列了。讓我們把這個(gè)標(biāo)準(zhǔn)傳遞給索引運(yùn)算符嚼吞,只選擇大于10的值盒件。

s[criteria].head()
17     16
76     14
566    11
763    12
781    19
Name: commentcount, dtype: int64

我們可以像這樣一步到位地完成這個(gè)工作

 s[s > 10].head()
17     16
76     14
566    11
763    12
781    19
Name: commentcount, dtype: int64

如果我們想找到那些大于10但小于15的評論,我們可以使用一個(gè)和條件舱禽,像這樣炒刁。

 s[(s > 10) & (s < 15)].head()
76     14
566    11
763    12
787    12
837    13
Name: commentcount, dtype: int64

另一種可能是between方法
Pandas中內(nèi)置了很多重復(fù)的功能。與其像上面那樣寫兩個(gè)布爾條件來選擇一個(gè)范圍內(nèi)的所有值誊稚,你可以使用between方法來創(chuàng)建一個(gè)布爾系列翔始。使用時(shí)罗心,將范圍的左端和右端點(diǎn)傳給它。這些端點(diǎn)是包括在內(nèi)的城瞎。

因此渤闷,為了復(fù)制前面的例子,你可以這樣做脖镀。

s[s.between(11, 14)].head()
76     14
566    11
763    12
787    12
837    13
Name: commentcount, dtype: int64

用.loc同時(shí)選擇行和列標(biāo)簽的布爾值
.loc索引器在第一部分中已經(jīng)徹底介紹了飒箭,現(xiàn)在將在這里介紹同時(shí)選擇行和列。在第一部分中蜒灰,我們說過.loc只通過標(biāo)簽進(jìn)行選擇弦蹂。這并不嚴(yán)格,因?yàn)樗材茉诎礃?biāo)簽選擇的同時(shí)進(jìn)行布爾式選擇卷员。

 So.loc[(so['score'] >= 5) & (so['ans_name'] == 'Scott Boston')] 
 criteria = so['ans_name'].isin(['Scott Boston', 'Ted Petrou', 
                                    'MaxU', 'unutbu'])
 so.loc[criteria].head()

.loc的行和列的選擇用逗號分開
.loc的最大好處是盈匾,它允許你同時(shí)沿著行做布爾選擇,并通過標(biāo)簽進(jìn)行列選擇

例如毕骡,假設(shè)我們想找到所有瀏覽量超過20k的問題削饵,但只返回creationdate、viewcount和ans_name列你可以做如下操作

 so.loc[so['viewcount'] > 20000, ['creationdate', 'viewcount', 
                                     'ans_name']].head(10)

你可以像這樣把每個(gè)選擇分成幾塊

 row_selection = so['viewcount'] > 20000
 col_selection = ['creationdate', 'viewcount', 'ans_name']
 so.loc[row_selection, col_selection] 

用.loc可以有很多的組合
記住未巫,.loc可以接受一個(gè)字符串窿撬、一個(gè)字符串列表或一個(gè)片斷你可以使用所有三種可能的方式來選擇你的數(shù)據(jù)你還可以為你的行做非常復(fù)雜的布爾選擇

讓我們來選擇 favoritecount 在 30 和 40 之間的行,以及從標(biāo)題開始到最后的每三列 奇怪但可行

代碼塊

so.loc[so['favoritecount'].between(30, 40), 'title':3].head()

對列進(jìn)行布爾選擇叙凡?
實(shí)際上是可以用一串布爾值來選擇列的你將一個(gè)長度與列數(shù)相同的布爾值的列表劈伴、系列或數(shù)組傳遞給.loc

讓我們做一個(gè)簡單的手工例子,我們手工創(chuàng)建一個(gè)布爾運(yùn)算的列表首先,讓我們找出在我們的數(shù)據(jù)集中有多少列

 so.shape
(56398, 12)

讓我們創(chuàng)建一個(gè)有12個(gè)布爾的列表

col_bools = [True, False, False] * 4
col_bools
[True,
 False,
 False,
 True,
 False,
 False,
 True,
 False,
 False,
 True,
 False,
 False]

使用.loc從col_bools中選擇所有只有True列的行

 so.loc[:, col_bools].head()

你也可以同時(shí)選擇行和列讓我們選擇同樣的列楞捂,但選擇有超過500,000次瀏覽的行

 so.loc[so['viewcount'] > 500000, col_bools] 

一個(gè)更實(shí)際的例子
讓我們來看看在列上做布爾選擇的一個(gè)稍微實(shí)際一點(diǎn)的例子假設(shè)我們將10個(gè)硬幣翻轉(zhuǎn)了100次纬向,并將每一次試驗(yàn)存儲在下面的DataFrame的一個(gè)列中

 coins = pd.DataFrame(np.random.randint(0, 2, (100, 10))
                         columns=list('abcdefghij'))
 coins.head()

 coins.shape
(100, 10)

如果我們對只選擇有50%以上的頭的列感興趣,我們可以首先像這樣取每一列的平均值

coin_mean = coins.mean()
coin_mean
a    0.50
b    0.46
c    0.48
d    0.47
e    0.43
f    0.52
g    0.44
h    0.47
i    0.57
j    0.44
dtype: float64

讓我們測試一下百分比大于0.5的條件

coin_mean > .5
a    False
b    False
c    False
d    False
e    False
f     True
g    False
h    False
i     True
j    False
dtype: bool

最后追城,我們可以使用這個(gè)布爾系列,只選擇符合我們條件的列

 coins.loc[:, coins.mean() > .5].head()

列與列之間的比較
之前所有的系列比較都是針對一個(gè)單一的標(biāo)量值進(jìn)行的我們可以通過將一列與另一列進(jìn)行比較來創(chuàng)建一個(gè)布爾系列例如燥撞,我們可以找到所有答案多于分?jǐn)?shù)的問題

 criteria = so['answerercount'] > so['score'] 
 so[criteria].head()

在一行中座柱,上面的內(nèi)容會是這樣的

 so[so['answerercount'] > so['score']] 

幾乎不要在布爾選擇中使用.iloc
首先,記住.iloc使用INTEGER位置來進(jìn)行選擇

你將很少使用.iloc來做布爾選擇物舒,幾乎總是只使用索引操作符或.loc為了了解原因色洞,讓我們嘗試運(yùn)行一個(gè)簡單的布爾選擇,找到所有擁有超過100,000個(gè)視圖的行

 so.iloc[so['viewcount'] > 100000]

NotImplementedError:
基于iLocation的整數(shù)類型的布爾索引不可用

NotImplementedError

pandas開發(fā)者還沒有決定對.iloc進(jìn)行布爾選擇(用系列)冠胯,所以它不能工作然而火诸,你可以將系列轉(zhuǎn)換為一個(gè)列表或NumPy數(shù)組,作為一種變通方法

讓我們把我們的系列保存為一個(gè)變量并仔細(xì)檢查其類型

 criteria = so['viewcount'] > 100000
 type(criteria)
pandas.core.series.Series

讓我們用values屬性抓取底層的NumPy數(shù)組涵叮,并把它傳遞給.iloc

 a = criteria.values
 so.iloc[a].head()

你也可以用整數(shù)進(jìn)行同步列選擇

 so.iloc[a, [5, 10, 11]].head()

我想我從來沒有將.iloc用于布爾選擇惭蹂,因?yàn)樗鼪]有實(shí)現(xiàn)系列伞插。我添加的原因是它是pandas中三個(gè)主要的索引器之一,重要的是要知道它在布爾選擇中根本就不怎么用盾碗。

s = so['score']
s[s > 100].head()
8      201
17     136
75     199
100    144
106    340
Name: score, dtype: int64

.loc和[]在系列中對布爾選擇的作用是一樣的媚污。
布爾選擇在.loc中的作用與在系列中的索引操作符中的作用是一樣的。當(dāng)傳遞一個(gè)布爾系列時(shí)廷雅,兩個(gè)索引器都會進(jìn)行行選擇耗美。由于Series沒有列,在這種情況下航缀,兩個(gè)索引器是相同的商架。

s.loc[s > 100].head()
8      201
17     136
75     199
100    144
106    340
Name: score, dtype: int64

摘要
布爾索引或布爾選擇是根據(jù)數(shù)值本身而不是行/列標(biāo)簽或整數(shù)位置來選擇一個(gè)系列/數(shù)據(jù)框架的子集。
布爾選擇用于回答常見的查詢芥玉,如 "找到所有年薪超過15萬的女工程師"
要進(jìn)行布爾選擇蛇摸,首先要創(chuàng)建一個(gè)真/假值的序列,并將其傳遞給DataFrame/系列索引器
每一行數(shù)據(jù)被保留或丟棄
索引操作符是重載的--根據(jù)傳遞給它們的內(nèi)容來改變功能
通常情況下灿巧,你將首先用6個(gè)比較運(yùn)算符中的一個(gè)創(chuàng)建一個(gè)布爾系列
你將把這個(gè)布爾系列傳遞給其中一個(gè)索引器來進(jìn)行選擇
使用isin方法來測試同一列中是否有多個(gè)相等的數(shù)據(jù)
使用isnull來查找某一列中所有缺失值的行
可以使用between系列方法來測試系列值是否在一個(gè)范圍內(nèi)
你可以用and (&), or (|), and not (~)邏輯運(yùn)算符創(chuàng)建復(fù)雜的條件
當(dāng)你在一行中有多個(gè)條件時(shí)赶袄,你必須用圓括號來包裹每個(gè)表達(dá)式。
如果你有復(fù)雜的條件抠藕,考慮將每一組條件存儲到它自己的變量中(也就是說饿肺,不要在一行中做所有的事情)。
如果你只選擇行盾似,那么你幾乎總是只使用索引操作符
如果你同時(shí)對行進(jìn)行布爾選擇并選擇列標(biāo)簽敬辣,那么你將使用.loc
你幾乎不會使用.iloc來做布爾選擇。
布爾選擇對系列的作用和對數(shù)據(jù)框架的作用是一樣的

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末零院,一起剝皮案震驚了整個(gè)濱河市溉跃,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌告抄,老刑警劉巖喊积,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異玄妈,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)髓梅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門拟蜻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人枯饿,你說我怎么就攤上這事酝锅。” “怎么了奢方?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵搔扁,是天一觀的道長爸舒。 經(jīng)常有香客問我,道長稿蹲,這世上最難降的妖魔是什么扭勉? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮苛聘,結(jié)果婚禮上涂炎,老公的妹妹穿的比我還像新娘。我一直安慰自己设哗,他們只是感情好唱捣,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著网梢,像睡著了一般震缭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上战虏,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天拣宰,我揣著相機(jī)與錄音,去河邊找鬼活烙。 笑死徐裸,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的啸盏。 我是一名探鬼主播重贺,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼回懦!你這毒婦竟也來了气笙?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤怯晕,失蹤者是張志新(化名)和其女友劉穎潜圃,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舟茶,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谭期,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吧凉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片隧出。...
    茶點(diǎn)故事閱讀 40,503評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖阀捅,靈堂內(nèi)的尸體忽然破棺而出胀瞪,到底是詐尸還是另有隱情,我是刑警寧澤饲鄙,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布凄诞,位于F島的核電站圆雁,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏帆谍。R本人自食惡果不足惜伪朽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望既忆。 院中可真熱鬧驱负,春花似錦、人聲如沸患雇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽苛吱。三九已至酪术,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間翠储,已是汗流浹背绘雁。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留援所,地道東北人庐舟。 一個(gè)月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像住拭,于是被迫代替她去往敵國和親挪略。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容