給初學(xué)者的 Jupyter Notebook 教程
Jupyter Notebook 是一個非常強大的工具披坏,常用于交互式地開發(fā)和展示數(shù)據(jù)科學(xué)項目句灌。它將代碼和它的輸出集成到一個文檔中贰逾,并且結(jié)合了可視的敘述性文本欣硼、數(shù)學(xué)方程和其他豐富的媒體樊破。它直觀的工作流促進(jìn)了迭代和快速的開發(fā)缕探,使得 notebook 在當(dāng)代數(shù)據(jù)科學(xué)魂莫、分析和越來越多的科學(xué)研究中越來越受歡迎。最重要的是爹耗,作為開源項目的一部分耙考,它們是完全免費的。
Jupyter 項目是早期 IPython Notebook 的繼承者潭兽,它在 2010 年首次作為原型發(fā)布倦始。盡管在 Jupyter Notebook 中可以使用許多不同的編程語言,但本文將重點介紹 Python山卦,因為在 Jupyter Notebook 中 python 是最常見的鞋邑。
為了充分理解本教程,你應(yīng)該熟悉編程,特別是 Python 和 pandas(譯者注:Pandas 是python的一個數(shù)據(jù)分析包)枚碗。也就是說逾一,如果你有編程經(jīng)驗,這篇文章中的 Python 不會太陌生肮雨,而 pandas 也是容易理解的遵堵。Jupyter Notebooks 也可以作為一個靈活的平臺來運行 pandas 甚至是 Python,這將在這篇文章中體現(xiàn)怨规。
我們將會:
- 介紹一些安裝 Jupyter 和創(chuàng)建你的第一個 notebook 的基本知識陌宿。
- 深入鉆研,學(xué)習(xí)所有重要的術(shù)語波丰。
- 探索筆記是如何輕松地在網(wǎng)上共享和發(fā)布壳坪。事實上,這篇文章就是一個 Jupyter notebook掰烟!這里的一切都是在 Jupyter notebook 環(huán)境中編寫的爽蝴,而你正在以只讀的形式查看它。
Jupyter Notebook 數(shù)據(jù)分析實例
我們將通過一個樣本分析媚赖,來回答一個真實的問題霜瘪,這樣你就可以看到一個 notebook 的工作流是如何使任務(wù)直觀地完成的,當(dāng)我們分享給其他人時也可以讓其他人更好地理解惧磺。
假設(shè)你是一名數(shù)據(jù)分析師,你的任務(wù)是弄清楚美國最大公司的利潤變化歷史捻撑。你會發(fā)現(xiàn)自從 1955 年第一次發(fā)表這個名單以來磨隘,已有超過 50 年的財富 500 強企業(yè)的數(shù)據(jù)集,這些數(shù)據(jù)都是從《財富》的公共檔案中收集來的顾患。我們已經(jīng)創(chuàng)建了一個可用數(shù)據(jù)的 CSV 文件(你可以在這里獲取它)番捂。
正如我們將要演示的,Jupyter Notebooks 非常適合這項調(diào)查江解。首先设预,讓我們安裝 Jupyter。
安裝
初學(xué)者開始使用 Jupyter Notebooks 的最簡單方法是安裝 Anaconda犁河。Anaconda 是最廣泛使用的用于數(shù)據(jù)科學(xué)的 Python 發(fā)行版鳖枕,并且預(yù)裝了所有常用的庫和工具。除了 Jupyter 之外桨螺,Anaconda 中還封裝了一些 Python 庫宾符,包括 NumPy,pandas 和 Matplotlib灭翔,并且這完整的1000+列表是詳盡的魏烫。這使你可以在自己完備的數(shù)據(jù)科學(xué)研討會中運行,而不需要管理無數(shù)的安裝包或擔(dān)心依賴項和特定操作系統(tǒng)的安裝問題。
安裝 Anaconda:
- 下載支持 Python 3 (就不用 Python 2.7 了)的最新版本 Anaconda哄褒。
- 按照下載頁面或可執(zhí)行文件中的說明安裝 Anaconda稀蟋。
如果你是已經(jīng)安裝了 Python 的更高級的用戶,并且更喜歡手動管理你的軟件包呐赡,那么你可以使用pip:
pip3 install jupyter
創(chuàng)建你的第一個 Notebook
在本節(jié)中退客,我們將看到如何運行和保存 notebooks,熟悉它們的結(jié)構(gòu)罚舱,并理解接口井辜。我們將會熟悉一些核心術(shù)語,這些術(shù)語將引導(dǎo)你對如何使用 Jupyter notebooks 進(jìn)行實際的理解管闷,并為下一節(jié)做鋪墊粥脚,該部分將通過示例數(shù)據(jù)分析,并將我們在這里學(xué)到的所有東西帶到生活中包个。
運行 Jupyter
在 Windows 上刷允,你可以通過將 Anaconda 快捷方式添加到你的開始菜單來運行 Jupyter,它將在你的默認(rèn)網(wǎng)頁瀏覽器中打開一個新的標(biāo)簽碧囊,看起來就像下面的截圖一樣树灶。
這是 Notebook Dashboard,專門用于管理 Jupyter Notebooks糯而。把它看作是探索天通,編輯和創(chuàng)建 notebooks 的啟動面板。你可以把它看作是探索熄驼、編輯和創(chuàng)造你的 notebook 的發(fā)射臺像寒。
請注意,儀表板將只允許您訪問 Jupyter 啟動目錄中包含的文件和子文件夾瓜贾;但是诺祸,啟動目錄是可以更改的。還可以通過輸入 jupyter notebook
命令在任何系統(tǒng)上啟動指示板(或在Unix系統(tǒng)上的終端);在這種情況下祭芦,當(dāng)前工作目錄將是啟動目錄筷笨。
聰明的讀者可能已經(jīng)注意到,儀表板的 URL 類似于 http://localhost:8888/tree
龟劲。Localhost 不是一個網(wǎng)站胃夏,而是表示從你的本地機器(你自己的計算機)中服務(wù)的內(nèi)容。Jupyter notebook 和儀表板都是 web 應(yīng)用程序咸灿,Jupyter 啟動了一個本地的 Python 服務(wù)器构订,將這些應(yīng)用程序提供給你的 web 瀏覽器,使其從根本上獨立于平臺避矢,并打開了更容易在 web 上共享的大門悼瘾。
儀表板的界面大部分是不言自明的 —— 盡管我們稍后會簡要介紹它囊榜。我們還在等什么?瀏覽到你想要創(chuàng)建你的第一個 notebook 的文件夾,點擊右上角的 New
下拉按鈕亥宿,選擇 Python 3
(或者你喜歡的版本)卸勺。
我們馬上能看到成果了!你的第一個 Jupyter Notebook 將在新標(biāo)簽頁打開 - 每個 notebook 使用它自己的標(biāo)簽,因為你可以同時打開多個 notebook烫扼。如果您切換回儀表板曙求,您將看到新文件 Untitled
。你應(yīng)該看到一些綠色的文字告訴 notebook 正在運行映企。
什么是 ipynb 文件悟狱?
理解這個文件到底是什么是很有用的。每一個 .ipynb
文件是一個文本文件堰氓,它以一種名為 JSON 的格式描述你的 notebook 的內(nèi)容挤渐。每個單元格及其內(nèi)容,包括已被轉(zhuǎn)換成文本字符串的圖像附件双絮,都與一些元數(shù)據(jù)一起列出浴麻。你可以自己編輯這個 -- 如果你知道你在做什么! -- 通過在 notebook 的菜單欄中選擇 "Edit > Edit Notebook Metadata"。
你還可以通過在儀表板上的控件中選擇 Edit
來查看你的 notebook 文件的內(nèi)容囤攀,但是重要的是可以软免;除了好奇之外沒有理由這樣做,除非你真的知道你在做什么焚挠。
notebook 的接口
既然你面前有一個打開的 notebook膏萧,它的界面就不會看起來完全陌生;畢竟蝌衔,Jupyter 實際上只是一個高級的文字處理器向抢。為什么不看一看?查看菜單以了解它胚委,尤其是花點時間瀏覽命令選項板(這是帶鍵盤圖標(biāo)的小按鈕(或 Ctrl + Shift + P
))下滾動命令列表。
您應(yīng)該注意到兩個非常重要的術(shù)語叉信,這對您來說可能是全新的:單元格和內(nèi)核亩冬。它們是理解 Jupyter 和區(qū)分 Jupyter 不只是一個文字處理器的關(guān)鍵。幸運的是硼身,這些概念并不難理解硅急。
- 內(nèi)核是一個“計算引擎”,它執(zhí)行一個 notebook 文檔中包含的代碼佳遂。
- 單元格是一個容器营袜,用于裝載在 notebook 中顯示的文本或是會被 notebook 內(nèi)核執(zhí)行的代碼。
單元格
稍后我們再討論內(nèi)核丑罪,在這之前我們先來了解一下單元格荚板。單元格構(gòu)成一個筆記本的主體凤壁。在上面一節(jié)的新建的 notebook 屏幕截圖中,帶有綠色輪廓的盒子是一個空的單元格跪另。我們將介紹兩種主要的單元格類型:
- 代碼單元包含要在內(nèi)核中執(zhí)行的代碼拧抖,并在下面顯示它的輸出。
- Markdown 單元包含使用 Markdown 格式化的文本免绿,并在運行時顯示其輸出唧席。
新的 notebook 中的第一個單元總是一個代碼單元。讓我們用一個經(jīng)典的 hello world 示例來測試它嘲驾。輸入 print('Hello World!')
到單元格中淌哟,點擊上面工具欄中的 run 按鈕,或者按下 Ctrl + Enter 鍵辽故。結(jié)果應(yīng)該是這樣的:
print('Hello World!')
Hello World!
當(dāng)你運行這個單元格時徒仓,它的輸出將會顯示在它的下面,而它左邊的標(biāo)簽將會從 In [ ]
變?yōu)?In [1]
榕暇。代碼單元的輸出也是文檔的一部分蓬衡,這就是為什么你可以在本文中看到它的原因。你總是可以區(qū)分代碼和 Markdown 單元彤枢,因為代碼單元格在左邊有標(biāo)簽狰晚,而 Markdown 單元沒有。標(biāo)簽的“In”部分僅僅是“輸入”的縮寫缴啡,而標(biāo)簽號表示在內(nèi)核上執(zhí)行單元格時的順序 —— 在這種情況下壁晒,單元格被第一個執(zhí)行。再次運行單元格业栅,標(biāo)簽將更改為 In[2]
秒咐,因為此時單元格是在內(nèi)核上運行的第二個單元格。這讓我們在接下來對內(nèi)核的深入將非常有用碘裕。
從菜單欄中携取,單擊插入并選擇在下方插入單元格,創(chuàng)建你新的代碼單元帮孔,并嘗試下面的代碼雷滋,看看會發(fā)生什么。你注意到有什么不同嗎?
import time
time.sleep(3)
這個單元不產(chǎn)生任何輸出文兢,但執(zhí)行需要 3 秒晤斩。請注意,Jupyter 將標(biāo)簽更改為 In[*]
來表示單元格當(dāng)前正在運行姆坚。
一般來說澳泵,單元格的輸出來自于單元執(zhí)行過程中指定打印的任何文本數(shù)據(jù),以及單元格中最后一行的值兼呵,無論是單獨變量兔辅,函數(shù)調(diào)用還是其他內(nèi)容腊敲。例如:
def say_hello(recipient):
return 'Hello, {}!'.format(recipient)
say_hello('Tim')
'Hello, Tim!'
你會發(fā)現(xiàn)自己經(jīng)常在自己的項目中使用它,以后我們會看到更多幢妄。
鍵盤快捷鍵
在運行單元格時兔仰,你可能經(jīng)常看到它們的邊框變成了藍(lán)色蕉鸳,而在編輯的時候它是綠色的乎赴。總是有一個“活動”單元格突出顯示其當(dāng)前模式潮尝,綠色表示“編輯模式”绿店,藍(lán)色表示“命令模式”绑洛。
到目前為止劳澄,我們已經(jīng)看到了如何使用 Ctrl + Enter
來運行單元格皂林,但是還有很多。鍵盤快捷鍵是 Jupyter 環(huán)境中非常流行的一個方面乱凿,因為它們促進(jìn)了快速的基于單元格的工作流顽素。許多這些都是在命令模式下可以在活動單元上執(zhí)行的操作。
下面徒蟆,你會發(fā)現(xiàn)一些 Jupyter 的鍵盤快捷鍵列表胁出。你可能不會馬上熟悉它們,但是這份清單應(yīng)該讓你對這些快捷鍵有了了解段审。
- 在編輯和命令模式之間切換全蝶,分別使用
Esc
和Enter
。 - 在命令行模式下:
- 用
Up
和Down
鍵向上和向下滾動你的單元格寺枉。 - 按
A
或B
在活動單元上方或下方插入一個新單元抑淫。 -
M
將會將活動單元格轉(zhuǎn)換為 Markdown 單元格。 -
Y
將激活的單元格設(shè)置為一個代碼單元格姥闪。 -
D + D
(按兩次D
)將刪除活動單元格始苇。 -
Z
將撤銷單元格刪除。 - 按住
Shift
筐喳,同時按Up
或Down
埂蕊,一次選擇多個單元格。- 選擇了 multple疏唾,
Shift + M
將合并你的選擇。
- 選擇了 multple疏唾,
- 用
-
Ctrl + Shift + -
函似,在編輯模式下槐脏,將在光標(biāo)處拆分活動單元格。 - 你也可以在你的單元格的左邊用
Shift + Click
來選擇它們撇寞。
你可以在自己的 notebook 上試試這些顿天。一旦你有了嘗試堂氯,創(chuàng)建一個新的 Markdown 單元,我們將學(xué)習(xí)如何在我們的 notebook 中格式化文本牌废。
Markdown
Markdown 是一種輕量級的咽白、易于學(xué)習(xí)的標(biāo)記語言,用于格式化純文本鸟缕。它的語法與 HTML 標(biāo)記有一對一的對應(yīng)關(guān)系晶框,所以這里的一些經(jīng)驗是有用的,但絕對不是先決條件懂从。請記住授段,這篇文章是在一個 Jupyter notebook 上寫的,所以你所看到的所有的敘述文本和圖片都是在 Markdown 完成的番甩。讓我們用一個簡單的例子來介紹基礎(chǔ)知識侵贵。
# 這是一級標(biāo)題。
## 這是一個二級標(biāo)題缘薛。
這是一些構(gòu)成段落的純文本窍育。
通過 **粗體** 和 __bold__ ,或 *斜體* 和 _italic_ 添加重點宴胧。
段落必須用空行隔開漱抓。
* 有時我們想要包含列表。
* 可以縮進(jìn)牺汤。
1. 列表也可以編號辽旋。
2. 有序列表。
[有可能包括超鏈接](https://www.example.com)
內(nèi)聯(lián)代碼使用單個倒引號:`foo()`檐迟,代碼塊使用三個倒引號:
\```
\bar()
\```
或可由4個空格組成:
foo()
最后补胚,添加圖片也很簡單:![Alt](https://www.example.com/image.jpg)
當(dāng)附加圖像時,你有三個選項:
使用一個在 web 上的圖像的 URL追迟。
使用一個與你的 notebook 一起維護(hù)的本地 URL溶其,例如在同一個 git 倉庫中。
通過 "Edit > Insert Image" 添加附件敦间;這將把圖像轉(zhuǎn)換成字符串并存儲在你的 notebook 中的
.ipynb
文件瓶逃。注意這將使你的
.ipynb
的文件更大!
Markdown 有很多細(xì)節(jié),特別是在超鏈接的時候廓块,也可以簡單地包括純 HTML厢绝。一旦你發(fā)現(xiàn)自己突破了上述基礎(chǔ)的限制,你可以參考 Markdown 創(chuàng)造者 John Gruber 的官方指南带猴。
內(nèi)核
每個 notebook 后臺都運行一個內(nèi)核昔汉。當(dāng)你運行一個代碼單元時,該代碼在內(nèi)核中執(zhí)行拴清,任何輸出都會返回到要顯示的單元格靶病。在單元格間切換時內(nèi)核的狀態(tài)保持不變 —— 它與文檔有關(guān)会通,而不是單個的單元格。
例如娄周,如果你在一個單元中導(dǎo)入庫或聲明變量涕侈,那么它們將在另一個單元中可用。通過這種方式煤辨,你可以將 notebook 文檔看作是與腳本文件相當(dāng)?shù)纳烟危怂嵌嗝襟w。讓我們試著去感受一下掷酗。首先调违,我們將導(dǎo)入一個 Python 包并定義一個函數(shù)。
import numpy as np
def square(x):
return x * x
一旦我們執(zhí)行了上面的單元格泻轰,我們就可以在任何其他單元中引用 np
和 square
技肩。
x = np.random.randint(1, 10)
y = square(x)
print('%d squared is %d' % (x, y))
1 squared is 1
不管你的 notebook 里的單元格順序如何,這都是可行的浮声。你可以自己試一下虚婿,讓我們再把變量打印出來。
print('Is %d squared is %d?' % (x, y))
Is 1 squared is 1?
答案毫無疑問泳挥。讓我們嘗試改變 y
然痊。
y = 10
如果我們再次運行包含 print
語句的單元格,你認(rèn)為會發(fā)生什么?我們得到的結(jié)果是 Is 4 squared is 10?
屉符!
大多數(shù)情況下剧浸,你的 notebook 上的工作流將會從上到下,但是返回上文做一些改變是很正常的矗钟。在這種情況下唆香,每個單元的左側(cè)的執(zhí)行順序,例如 In [6]
吨艇,將讓你知道你的任何單元格是否有陳舊的輸出躬它。如果你想要重置一些東西,從內(nèi)核菜單中有幾個非常有用的選項:
- 重啟:重新啟動內(nèi)核东涡,從而清除定義的所有變量冯吓。
- 重啟和清除輸出:與上面一樣,但也將擦除顯示在您的代碼單元格下面的輸出疮跑。
- 重啟和運行所有:和上面一樣组贺,但也會運行你的所有單元,從第一個到最后祖娘。
如果你的內(nèi)核一直在計算中锣披,但你希望停止它,你可以選擇 Interupt
選項。
選擇一個內(nèi)核
你可能已經(jīng)注意到雹仿,Jupyter 提供了更改內(nèi)核的選項,實際上有許多不同的選項可供選擇整以。當(dāng)你通過選擇 Python 版本從儀表板中創(chuàng)建一個新的筆記時胧辽,你實際上是在選擇使用哪個內(nèi)核。
不僅有不同版本的 Python 的內(nèi)核公黑,還有(超過 100 種語言)邑商,包括 Java 、C 凡蚜,甚至 Fortran人断。數(shù)據(jù)科學(xué)家可能特別感興趣的是 R 和 Julia,以及 imatlab 和 Calysto MATLAB內(nèi)核 朝蜘。SoS 內(nèi)核在一個 notebook 中提供多語言支持恶迈。每個內(nèi)核都有自己的安裝指令,但可能需要您在計算機上運行一些命令谱醇。
實例分析
現(xiàn)在我們已經(jīng)看了一個 Jupyter Notebook暇仲,是時候看看它們在實踐中使用了,這應(yīng)該會讓你更清楚地了解它們?yōu)槭裁茨敲词軞g迎「笨剩現(xiàn)在是時候開始使用前面提到的財富 500 數(shù)據(jù)集了奈附。請記住,我們的目標(biāo)是了解美國最大公司的利潤在歷史上是如何變化的煮剧。
值得注意的是斥滤,每個人都會有自己的喜好和風(fēng)格,但是一般原則仍然適用勉盅,如果你愿意佑颇,你可以在自己的 notebook 上跟隨這一段,這也給了你自由發(fā)揮空間菇篡。
命名你的 notebook
在開始編寫項目之前漩符,你可能想要給它一個有意義的名稱。也許有點讓人困惑驱还,你不能從 Notebook 的應(yīng)用程序中命名或重命名你的 notebook嗜暴,而必須使用儀表盤或你的文件瀏覽器來重命名 .ipynb
文件。我們將返回到儀表板议蟆,以重命名你之前創(chuàng)建的文件闷沥,它將有默認(rèn)的 notebook 的文件名是 Untitled.ipynb
。
你不能在 notebook 運行時重命名它咐容,所以你首先要關(guān)閉它舆逃。最簡單的方法就是從 notebook 菜單中選擇 “File > Close and Halt”。但是,您也可以通過在筆記本應(yīng)用程序內(nèi) “Kernel > Shutdown” 或在儀表板中選擇 notebook 并點擊 “Shutdown” (見下圖)來關(guān)閉內(nèi)核路狮。
然后你可以選擇你的 notebook虫啥,并在儀表板控件中點擊 “Rename”。
注意奄妨,在你的瀏覽器中關(guān)閉筆記的標(biāo)簽頁將不會像在傳統(tǒng)的應(yīng)用程序中關(guān)閉文檔的方式一樣關(guān)閉你的 notebook涂籽。notebook 的內(nèi)核將繼續(xù)在后臺運行,需要在真正“關(guān)閉”之前停止運行 —— 不過如果你不小心關(guān)掉了你的標(biāo)簽或瀏覽器砸抛,這就很方便了评雌!如果內(nèi)核被關(guān)閉,你可以關(guān)閉該選項卡直焙,而不用擔(dān)心它是否還在運行景东。
如果你給你的 notebook 起了名字,打開它奔誓,我們就可以開始實踐了斤吐。
設(shè)置
通常一開始就使用一個專門用于導(dǎo)入和設(shè)置的代碼單元,因此如果你選擇添加或更改任何內(nèi)容丝里,你可以簡單地編輯和重新運行該單元曲初,而不會產(chǎn)生任何副作用。
%matplotlib inline
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style="darkgrid")
我們導(dǎo)入 pandas 來處理我們的數(shù)據(jù)杯聚,Matplotlib 繪制圖表臼婆,Seaborn 使我們的圖表更美。導(dǎo)入 NumPy 也是很常見的幌绍,但是在這種情況下颁褂,雖然我們使用的是 pandas,但我們不需要顯式地使用它傀广。第一行不是 Python 命令颁独,而是使用一種叫做行魔法的東西來指示 Jupyter 捕獲 Matplotlib 圖并在單元輸出中呈現(xiàn)它們;這是超出本文范圍的一系列高級特性之一伪冰。
讓我們來加載數(shù)據(jù)誓酒。
df = pd.read_csv('fortune500.csv')
在單個單元格中這樣做也是明智的,因為我們需要在任何時候重新加載它贮聂。
保存和檢查點
現(xiàn)在我們已經(jīng)開始了靠柑,最好的做法是定期存儲。按 Ctrl + S
鍵可以通過調(diào)用“保存和檢查點”命令來保存你的 notebook吓懈,但是這個檢查點又是什么呢?
每當(dāng)你創(chuàng)建一個新的 notebook 時歼冰,都會創(chuàng)建一個檢查點文件以及你的 notebook 文件;它將位于你保存位置的隱藏子目錄中稱作 .ipynb_checkpoints
耻警,也是一個 .ipynb
文件隔嫡。默認(rèn)情況下甸怕,Jupyter 將每隔 120 秒自動保存你的 notebook,而不會改變你的主 notebook 文件腮恩。當(dāng)你“保存和檢查點”時梢杭,notebook 和檢查點文件都將被更新。因此秸滴,檢查點使你能夠在發(fā)生意外事件時恢復(fù)未保存的工作式曲。你可以通過 “File > Revert to Checkpoint“ 從菜單恢復(fù)到檢查點。
調(diào)查我們的數(shù)據(jù)集
我們正在穩(wěn)步前進(jìn)缸榛!我們的筆記已經(jīng)被安全保存,我們將數(shù)據(jù)集 df
加載到最常用的 pandas 數(shù)據(jù)結(jié)構(gòu)中兰伤,這被稱為 DataFrame
内颗,看起來就像一張表格。那我們的數(shù)據(jù)集會是怎樣的敦腔?
df.head()
Year | Rank | Company | Revenue (in millions) | Profit (in millions) | |
---|---|---|---|---|---|
0 | 1955 | 1 | General Motors | 9823.5 | 806 |
1 | 1955 | 2 | Exxon Mobil | 5661.4 | 584.8 |
2 | 1955 | 3 | U.S. Steel | 3250.4 | 195.4 |
3 | 1955 | 4 | General Electric | 2959.1 | 212.6 |
4 | 1955 | 5 | Esmark | 2510.8 | 19.1 |
df.tail()
Year | Rank | Company | Revenue (in millions) | Profit (in millions) | |
---|---|---|---|---|---|
25495 | 2005 | 496 | Wm. Wrigley Jr. | 3648.6 | 493 |
25496 | 2005 | 497 | Peabody Energy | 3631.6 | 175.4 |
25497 | 2005 | 498 | Wendy's International | 3630.4 | 57.8 |
25498 | 2005 | 499 | Kindred Healthcare | 3616.6 | 70.6 |
25499 | 2005 | 500 | Cincinnati Financial | 3614.0 | 584 |
看上去不錯均澳。我們有需要的列,每一行對應(yīng)一個公司一年的財務(wù)數(shù)據(jù)符衔。
讓我們重命名這些列找前,以便稍后引用它們。
df.columns = ['year', 'rank', 'company', 'revenue', 'profit']
接下來判族,我們需要探索我們的數(shù)據(jù)集躺盛,它是否完整? pandas 是按預(yù)期讀的嗎?缺少值嗎?
len(df)
25500
好吧形帮,看起來不錯 —— 從 1955 年到 2005 年槽惫,每年都有 500 行。
讓我們檢查我們的數(shù)據(jù)集是否如我們預(yù)期的那樣被導(dǎo)入辩撑。一個簡單的檢查就是查看數(shù)據(jù)類型(或 dtypes)是否被正確地解釋界斜。
df.dtypes
year int64
rank int64
company object
revenue float64
profit object
dtype: object
看起來利潤欄有點問題 —— 我們希望它像收入欄一樣是 float64
。這表明它可能包含一些非整數(shù)值合冀,所以讓我們看一看各薇。
non_numberic_profits = df.profit.str.contains('[^0-9.-]')
df.loc[non_numberic_profits].head()
year | rank | company | revenue | profit | |
---|---|---|---|---|---|
228 | 1955 | 229 | Norton | 135.0 | N.A. |
290 | 1955 | 291 | Schlitz Brewing | 100.0 | N.A. |
294 | 1955 | 295 | Pacific Vegetable Oil | 97.9 | N.A. |
296 | 1955 | 297 | Liebmann Breweries | 96.0 | N.A. |
352 | 1955 | 353 | Minneapolis-Moline | 77.4 | N.A. |
就像我們猜測的那樣!其中一些值是字符串,用于表示丟失的數(shù)據(jù)君躺。還有其他缺失的值么?
set(df.profit[non_numberic_profits])
{'N.A.'}
這很容易解釋峭判,但是我們應(yīng)該怎么做呢?這取決于缺失了多少個值晰洒。
len(df.profit[non_numberic_profits])
369
它只是我們數(shù)據(jù)集的一小部分朝抖,雖然不是完全無關(guān)緊要,因為它仍然在 1.5% 左右谍珊。如果包含 N.A. 的行是簡單地治宣、均勻地按年分布的急侥,那最簡單的解決方案就是刪除它們。所以讓我們?yōu)g覽一下分布侮邀。
bin_sizes, _, _ = plt.hist(df.year[non_numberic_profits], bins=range(1955, 2006))
粗略地看坏怪,我們可以看到,在一年中無效值最多的情況也小于 25绊茧,并且由于每年有 500 個數(shù)據(jù)點铝宵,刪除這些值在最糟糕的年份中只占不到 4% 的數(shù)據(jù)。事實上华畏,除了 90 年代的激增鹏秋,大多數(shù)年份的缺失值還不到峰值的一半。為了我們的目的亡笑,假設(shè)這是可以接受的侣夷,然后移除這些行。
df = df.loc[~non_numberic_profits]
df.profit = df.profit.apply(pd.to_numeric)
我們看看有沒有生效仑乌。
len(df)
25131
df.dtypes
year int64
rank int64
company object
revenue float64
profit float64
dtype: object
不錯百拓!我們已經(jīng)完成了數(shù)據(jù)集的設(shè)置。
如果你要將 notebook 做成一個報告晰甚,你可以不使用我們創(chuàng)建的研究的單元格衙传,包括這里的演示使用 notebook 的工作流,合并相關(guān)單元格(請參閱下面的高級功能部分)并創(chuàng)建一個數(shù)據(jù)集設(shè)置單元格厕九。這意味著如果我們把我們的數(shù)據(jù)放在別處蓖捶,我們可以重新運行安裝單元來恢復(fù)它。
使用 matplotlib 進(jìn)行繪圖
接下來止剖,我們可以通過計算年平均利潤來解決這個問題腺阳。我們不妨把收入也畫出來,所以首先我們可以定義一些變量和一種方法來減少我們的代碼穿香。
group_by_year = df.loc[:, ['year', 'revenue', 'profit']].groupby('year')
avgs = group_by_year.mean()
x = avgs.index
y1 = avgs.profit
def plot(x, y, ax, title, y_label):
ax.set_title(title)
ax.set_ylabel(y_label)
ax.plot(x, y)
ax.margins(x=0, y=0)
現(xiàn)在讓我們開始畫圖亭引。
fig, ax = plt.subplots()
plot(x, y1, ax, 'Increase in mean Fortune 500 company profits from 1955 to 2005', 'Profit (millions)')
它看起來像一個指數(shù),但它有一些大的凹陷皮获。它們一定是對應(yīng)于上世紀(jì) 90 年代初的經(jīng)濟(jì)衰退和 互聯(lián)網(wǎng)泡沫焙蚓。在數(shù)據(jù)中能看到這一點非常有趣。但為什么每次經(jīng)濟(jì)衰退后洒宝,利潤都能恢復(fù)到更高的水平呢?
也許收入能告訴我們更多购公。
y2 = avgs.revenue
fig, ax = plt.subplots()
plot(x, y2, ax, 'Increase in mean Fortune 500 company revenues from 1955 to 2005', 'Revenue (millions)')
這為故事增添了另一面。收入幾乎沒有受到嚴(yán)重打擊雁歌,財務(wù)部門的會計工作做得很好宏浩。
借助 Stack Overflow 上的幫助,我們可以用 +/- 它們的標(biāo)準(zhǔn)偏移來疊加這些圖靠瞎。
def plot_with_std(x, y, stds, ax, title, y_label):
ax.fill_between(x, y - stds, y + stds, alpha=0.2)
plot(x, y, ax, title, y_label)
fig, (ax1, ax2) = plt.subplots(ncols=2)
title = 'Increase in mean and std Fortune 500 company %s from 1955 to 2005'
stds1 = group_by_year.std().profit.as_matrix()
stds2 = group_by_year.std().revenue.as_matrix()
plot_with_std(x, y1.as_matrix(), stds1, ax1, title % 'profits', 'Profit (millions)')
plot_with_std(x, y2.as_matrix(), stds2, ax2, title % 'revenues', 'Revenue (millions)')
fig.set_size_inches(14, 4)
fig.tight_layout()
這是驚人的比庄,標(biāo)準(zhǔn)偏差是巨大的求妹。一些財富 500 強的公司賺了數(shù)十億,而另一些公司卻損失了數(shù)十億美元佳窑,而且隨著這些年來利潤的增長制恍,風(fēng)險也在增加。也許有些公司比其他公司表現(xiàn)更好神凑;前 10% 的利潤是否或多或少會比最低的10%穩(wěn)定一些?
接下來我們有很多問題可以看净神,很容易看到在 notebook 上的工作流程是如何與自己的思維過程相匹配的,所以現(xiàn)在是時候為這個例子畫上句號了溉委。這一流程幫助我們在無需切換應(yīng)用程序的情況下輕松地研究我們的數(shù)據(jù)集鹃唯,并且我們的工作可以立即共享和重現(xiàn)。如果我們希望為特定的目標(biāo)人群創(chuàng)建一個更簡潔的報告瓣喊,我們可以通過合并單元和刪除中間代碼來快速重構(gòu)我們的工作俯渤。
分享你的 notebook
當(dāng)人們談?wù)摲窒硭麄兊?notebook 時,他們通常會考慮兩種模式型宝。大多數(shù)情況下,個人共享其工作的最終結(jié)果絮爷,就像本文本身一樣趴酣,這意味著共享非交互式的、預(yù)渲染的版本的 notebook坑夯;然而岖寞,也可以在 notebook 上借助諸如 Git 這樣的輔助版本控制系統(tǒng)進(jìn)行協(xié)作。
也就是說柜蜈,有一些新興的公司在 web 上提供了在云中運行交互式 Jupyter Notebook 的能力仗谆。
在你分享之前
當(dāng)你導(dǎo)出或保存它時,共享的 notebook 將會以被導(dǎo)出或保存的那一刻的狀態(tài)顯示淑履,包括所有代碼單元的輸出隶垮。因此,為了確保你的 notebook 是共享的秘噪,你可以在分享之前采取一些步驟:
- 點擊 "Cell > All Output > Clear"
- 點擊 "Kernel > Restart & Run All"
- 等待您的代碼單元完成執(zhí)行狸吞,并檢查它們是否按預(yù)期執(zhí)行。
這將確保你的 notebook 不包含中間輸出指煎,不包含陳舊的狀態(tài)蹋偏,并在共享時按順序執(zhí)行。
導(dǎo)出你的 notebook
Jupyter 內(nèi)置支持導(dǎo)出 HTML 和 PDF 以及其他幾種格式至壤,你可以在 File > Download As
菜單下找到威始。如果你希望與一個小型的私有組共享你的 notebook,這個功能很可能是你所需要的像街。事實上黎棠,許多學(xué)術(shù)機構(gòu)的研究人員都有一些公共或內(nèi)部的網(wǎng)絡(luò)空間晋渺,因為你可以將一個 notebook 導(dǎo)出到一個 HTML 文件中,Jupyter notebook 可以成為他們與同行分享成果的一種特別方便的方式葫掉。
但是些举,如果共享導(dǎo)出的文件并不能讓你滿意,那么還有一些更直接的非常流行的共享 .ipynb
文件到網(wǎng)上的方法俭厚。
GitHub
截止到 2018 年初户魏,GitHub 上的公共 notebook 數(shù)量超過了 180 萬,它無疑是最受歡迎的與世界分享 Jupyter 項目的獨立平臺挪挤。GitHub 已經(jīng)集成了對 .ipynb
的文件渲染的支持叼丑,你可以直接將其存儲在其網(wǎng)站的倉庫和 gists 中。如果你還不知道扛门,GitHub 是一個代碼托管平臺鸠信,用于為使用 Git 創(chuàng)建的存儲庫進(jìn)行版本控制和協(xié)作。你需要創(chuàng)建一個帳戶來使用他們的服務(wù)论寨,同時 Github 標(biāo)準(zhǔn)帳戶是免費的星立。
當(dāng)你有了 GitHub 賬戶,在 GitHub 上共享一個 notebook 最簡單的方法甚至都不需要 Git葬凳。自 2008 年以來绰垂, GitHub 為托管和共享代碼片段提供了Gist 服務(wù),每個代碼段都有自己的存儲庫火焰。使用 Gists 共享一個 notebook:
- 登錄并且瀏覽 gist.github.com劲装。
- 用文件編輯器打開
.ipynb
文件, 全選并且拷貝里面的 JSON 。 - 將筆記的 JSON 粘貼到中 gist 中昌简。
- 給你的 Gist 命名, 記得添加
.iypnb
后綴占业,否則不能正常工作。 - 點擊 "Create secret gist"或者 "Create public gist."
這看起來應(yīng)該是這樣的:
如果你創(chuàng)建了一個公共的 Gist纯赎,你現(xiàn)在就可以和任何人分享它的 URL谦疾,其他人將能夠 fork 和 clone 你的工作。
創(chuàng)建自己的 Git 存儲庫并在 GitHub 上共享犬金,這超出了本教程的范圍餐蔬,但是 GitHub 提供了大量的指南可供你參考。
對于那些使用 git 的人來說佑附,一個額外的技巧是在 .gitignore
中為 Jupyter 創(chuàng)建的 .ipynb_checkpoints
目錄添加例外樊诺,因為我們不需要將檢查點文件提交給到倉庫。
從 2015 年起音同,NBViewer 每個星期都會渲染成千上萬的 notebook词爬,它已然成了最受歡迎的 notebook 渲染器。如果你已經(jīng)在某個地方把你的 Jupyter Notebook 放在網(wǎng)上权均,無論是 GitHub 還是其他地方顿膨,NBViewer 都可以讀取你的 notebook锅锨,并提供一個可共享的 URL。作為項目 Jupyter 的一部分提供的免費服務(wù)恋沃,你可以在 nbview.jupyter.org 找到相關(guān)服務(wù)必搞。
最初是在 GitHub 的 Jupyter Notebook 集成之前開發(fā)的,NBViewer 允許任何人輸入 URL囊咏、Gist ID 或 GitHub username/repo/filename
恕洲,并將其作為網(wǎng)頁呈現(xiàn)。一個 Gist 的 ID 是其 URL 末尾唯一的數(shù)字梅割;例如霜第,在 https://gist.github.com/username/50896401c23e0bf417e89e1de
中最后一個反斜杠后的字符串。如果你輸入了 GitHub username/repo/filename
户辞,你將看到一個最小的文件瀏覽器泌类,它允許你訪問用戶的倉庫及其內(nèi)容。
NBViewer 顯示的 notebook 的 URL 是基于正在渲染的 notebook 的 URL 的并且不會改變底燎,所以你可以和任何人分享它刃榨,只要原始文件保持在線 —— NBViewer 不會緩存文件很長時間。
結(jié)語
從基礎(chǔ)知識入手双仍,我們已經(jīng)掌握了 Jupyter Notebook 的工作流程喇澡,深入研究了IPython 的更多高級功能,并最終學(xué)會如何與朋友殊校、同事和世界分享我們的工作。我們從一個筆記上完成了這一切!
可以看到读存,notebook 是如何通過減少上下文切換和在項目中模擬自然的思維發(fā)展的方式來提高工作經(jīng)驗的为流。Jupyter Notebook。Jupyter Notebook 的功能也應(yīng)該是顯而易見的让簿,我們已經(jīng)介紹了大量的資源敬察,讓你開始在自己的項目中探索更高級的特性。
如果你想為自己的 Notebooks 提供更多的靈感尔当,Jupyter 已經(jīng)整理好了(一個有趣的 Jupyter Notebook 圖庫)莲祸,你可能會發(fā)現(xiàn)它有幫助,并且你會發(fā)現(xiàn) Nbviewer 的主頁鏈接到一些真正的高質(zhì)量筆記本的例子椭迎。也可以查看我們的 Jupyter Notebooks 提示列表锐帜。
想了解更多關(guān)于 Jupyter Notebooks 的知識嗎?我們有一個有指導(dǎo)的項目,你可能會感興趣畜号。