計算與推斷思維 三、Python 編程

三甸私、Python 編程

原文:Programming in Python

譯者:飛龍

協(xié)議:CC BY-NC-SA 4.0

自豪地采用谷歌翻譯

編程可以極大地提高我們收集和分析世界信息的能力诚些,而這些信息又可以通過上一節(jié)所述的謹慎推理來發(fā)現。 在數據科學中皇型,編寫程序的目的是诬烹,指示計算機執(zhí)行分析步驟。 電腦無法自行研究世界弃鸦。 人們必須準確描述計算機應該執(zhí)行什么步驟來收集和分析數據绞吁,這些步驟是通過程序來表達的。

表達式

編程語言比人類語言簡單得多唬格。 盡管如此家破,在任何語言中,還是有一些語法規(guī)則需要學習购岗,這里就是我們開始的地方汰聋。 在本文中,我們將使用 Python 編程語言喊积。 學習語法規(guī)則是必不可少的烹困,最基本的程序中使用的規(guī)則也是更復雜程序的核心。

程序由表達式組成注服,向計算機描述了如何組合數據片段韭邓。 例如措近,乘法表達式由兩個數字表達式之間的*符號組成。表達式女淑,例如3*4瞭郑,由計算機求值。在這種情況下鸭你,(IPython 中的)每個單元格中的最后一個表達式的值(求值結果)將顯示在單元格下方屈张,這里是 12。

3 * 4
12

編程語言的語法規(guī)則是僵化的袱巨。 在 Python 中阁谆,*符號不能連續(xù)出現兩次。 計算機不會試圖解釋一個與規(guī)定的表達式結構不同的表達式愉老。 相反场绿,它會顯示SyntaxError錯誤。 語言的語法是其語法規(guī)則的集合嫉入,SyntaxError表示表達式結構不匹配任何語法規(guī)則焰盗。

3 * * 4
  File "<ipython-input-4-d90564f70db7>", line 1
    3 * * 4
        ^
SyntaxError: invalid syntax

表達式的小改動可以完全改變它的含義。 下面咒林,*之間的空格已被刪除熬拒。 因為**出現在兩個數字表達式之間,所以表達式是一個格式良好的指數表達式(第一個數字的第二個數字次方垫竞,3*3*3*3)澎粟。 符號***稱為運算符,它們組合的值稱為操作數欢瞪。

3 ** 4
81

常用操作符活烙。 數據科學通常涉及數值的組合,而編程語言中的一組操作符引有,是為了使得表達式可以用于表示任何類型的算術瓣颅。 在Python中,以下操作符是必不可少的譬正。

表達式類型 運算符 示例
加法 + 2 + 3 5
減法 - 2 - 3 -1
乘法 * 2 * 3 6
除法 / 7 / 3 2.66667
取余 % 7 % 3 1
指數 ** 2 ** 0.5 1.41421

Python 表達式遵循熟悉的優(yōu)先級規(guī)則宫补,與代數中相同:乘法和除法在加法和減法之前計算。 圓括號可以用來在較大的表達式中曾我,將較小的表達式組合在一起粉怕。

1 + 2 * 3 * 4 * 5 / 6 ** 3 + 7 + 8 - 9 + 10
17.555555555555557
1 + 2 * (3 * 4 * 5 / 6) ** 3 + 7 + 8 - 9 + 10
2017.0

示例

這里是一個圖表,來自 20 世紀 80 年代初期的“華盛頓郵報”(The Washington Post)抒巢,試圖比較幾十年來醫(yī)生的收入與其他專業(yè)人員的收入贫贝。 我們是否真的需要在每個條形上看到兩個頭(一個帶有聽診器)? 耶魯大學教授愛德華·圖夫特(Edward Tufte)是世界上量化信息可視化的專家之一,他為這種不必要的修飾創(chuàng)造了“垃圾圖表”(chartjunk)一詞稚晚。 這張圖也是 Tufte 痛恨的“數據與油墨比例過低”的一個例子崇堵。

image

華盛頓郵報圖片

最重要的是,圖的橫軸不是按比例繪制的。 這對條形圖的形狀有顯著的影響。 當按規(guī)模繪制并把裝飾修剪掉時编兄,圖表顯示的趨勢非常不同于原來明顯的線性增長。 下面的優(yōu)雅圖表由統(tǒng)計系統(tǒng) R 的創(chuàng)始人之一 Ross Ihaka 提供赏廓。

image

Ross Ihaka 的圖片版本

在 1939 年到 1963 年間,醫(yī)生的收入從 3,262 美元增加到 25,050 美元傍妒。 所以在這個時期幔摸,每年的平均收入增加了大約 900 美元。

(25050 - 3262)/(1963 - 1939)
907.8333333333334

在 Ross Ihaka 的圖表中可以看到颤练,在這個時期既忆,醫(yī)生的收入大致呈線性上升,并且保持在一個相對穩(wěn)定的水平嗦玖。 正如我們剛剛計算的那樣尿贫,這個比率大約是 900 美元。

但是從 1963 年到 1976 年踏揣,這個比例是三倍多:

(62799 - 25050)/(1976 - 1963)
2903.769230769231

這就是 1963 年之后,這個圖形急劇上升的原因匾乓。

本章介紹了許多類型的表達式捞稿。 學習編程需要結合學到所有的東西,調查計算機的行為拼缝。 如果你連續(xù)除兩次會發(fā)生什么娱局? 你并不需要總是問專家(或互聯(lián)網);許多這些細節(jié)可以通過自己嘗試發(fā)現咧七。

數值

整數值

計算機為執(zhí)行數值計算而設計衰齐,但是關于處理數字有一些重要的細節(jié),每個處理定量數據的程序員都應該知道它继阻。 Python(和大多數其他編程語言)區(qū)分兩種不同類型的數字:

  • 整數在 Python 語言中稱為int值耻涛。 它們只能表示沒有小數部分的整數(負數,零或正數)
  • 實數在 Python 語言中被稱為float值(或浮點值)瘟檩。 他們可以表示全部或部分數字抹缕,但有一些限制。

數值的類型在展示方式上是明顯的:int值沒有小數點墨辛,float值總是有一個小數點卓研。

# Some int values
2
2
1 + 3
4
-1234567890000000000
-1234567890000000000
# Some float values
1.2
1.2
1.5 + 2
3.5
3 / 1
3.0
-12345678900000000000.0
-1.23456789e+19

當一個float值和一個int值,通過算術運算符組合在一起時,結果總是一個float值奏赘。 在大多數情況下寥闪,兩個整數的組合形成另一個整數,但任何數字(intfloat)除以另一個將是一個float值磨淌。 非常大或非常小的float值可以使用科學記數法表示疲憋。

浮點值

浮點值非常靈活,但他們有限制伦糯。

float可以表示非常大和非常小的數字柜某。存在限制,但你很少遇到他們敛纲。
浮點數只能表示任何數字的 15 或 16 位有效數字喂击;剩下的精度就會丟失。 這個有限的精度對于絕大多數應用來說已經足夠了淤翔。
將浮點值與算術運算結合后翰绊,最后的幾位數字可能不正確。 第一次遇到時旁壮,微小的舍入錯誤往往令人困惑监嗜。

第一個限制可以通過兩種方式來觀察。 如果一個計算的結果是一個非常大的數字抡谐,那么它被表示為無限大裁奇。 如果結果是非常小的數字,則表示為零麦撵。

2e306 * 10
2e+307
2e306 * 100
inf
2e-322 / 10
2e-323
2e-322 / 100
0.0

第二個限制可以通過涉及超過 15 位有效數字的表達式來觀察刽肠。 在進行任何算術運算之前,這些額外的數字被丟棄免胃。

0.6666666666666666 - 0.6666666666666666123456789
0.0

當兩個表達式應該相等時音五,可以觀察到第三個限制。 例如羔沙,表達式2 ** 0.5計算 2 的平方根躺涝,但是該值的平方不會完全恢復成 2。

2 ** 0.5
1.4142135623730951
(2 ** 0.5) * (2 ** 0.5)
2.0000000000000004
(2 ** 0.5) * (2 ** 0.5) - 2
4.440892098500626e-16

上面的最終結果是0.0000000000000004440892098500626扼雏,這個數字非常接近零坚嗜。 這個算術表達式的正確答案是 0,但是最后的有效數字中的一個小錯誤呢蛤,在科學記數法中顯得非常不同惶傻。 這種行為幾乎出現在所有的編程語言中,因為它是在計算機上進行算術運算的標準方式的結果其障。

盡管float并不總是精確的银室,但它們當然是可靠的,并且在所有不同種類的計算機和編程語言中,以相同的方式工作蜈敢。

名稱

名稱通過賦值語句在 Python 中得到一個值辜荠。 在賦值中,名稱后面是=抓狭,再后面是任何表達式伯病。 =右邊的表達式的值被賦給名稱。 一旦名稱有了賦給它的值否过,在將來的表達式中午笛,值會替換為這個名稱。

a = 10
b = 20
a + b
30

之前賦值的名稱可以在=右邊的表達式中使用苗桂。

quarter = 1/4
half = 2 * quarter
half
0.5

但是药磺,僅僅是表達式的當前值賦給了名稱。 如果該值稍后改變煤伟,則由該值定義的名稱將不會自動更改癌佩。

quarter = 4
half
0.5

名稱必須以字母開頭,但可以包含字母和數字便锨。 名稱不能包含空格围辙;相反,通常使用下劃線字符_來替換每個空格放案。名稱只在你編寫的時候是有用的姚建;程序員可以選擇易于理解的名稱。 通常吱殉,比起ab桥胞,你可以創(chuàng)造更有意義的名字。 例如考婴,為了描述加利福尼亞州伯克利 5 美元商品的銷售稅,以下名稱闡明了各種相關數量的含義催烘。

purchase_price = 5
state_tax_rate = 0.075
county_tax_rate = 0.02
city_tax_rate = 0
sales_tax_rate = state_tax_rate + county_tax_rate + city_tax_rate
sales_tax = purchase_price * sales_tax_rate
sales_tax
0.475

示例:增長率

相同數量在不同時間取得的兩次測量值之間的關系通常表示為增長率沥阱。 例如,美國聯(lián)邦政府在 2002 年雇用了 276.6 萬人伊群,在 2012 年雇用了 281.4 萬人考杉。為了計算增長率,我們必須首先決定將哪個值作為初始值舰始。 對于隨著時間變化的數值崇棠,較早的值是一個自然的選擇。 然后丸卷,我們將變動值和初始值之間的差除以初始值枕稀。

initial = 2766000
changed = 2814000
(changed - initial) / initial
0.01735357917570499

通常從兩個測量值的比例中減去 1,這產生相同的值。

(changed/initial) - 1
0.017353579175704903

這個值是 10 年間的增長率萎坷。 增長率的一個實用屬性是凹联,即使值以不同的單位表示,它們也不會改變哆档。 所以蔽挠,例如,我們可以以千人為單位瓜浸,在 2002 年和 2012 年之間表達同樣的關系澳淑。

initial = 2766
changed = 2814
(changed/initial) - 1
0.017353579175704903

10 年以來,美國聯(lián)邦政府的雇員人數僅增長了 1.74%插佛。 那個時候杠巡,美國聯(lián)邦政府的總支出從 2.37 萬億美元增加到 2012 年的 3.38 萬億美元。

initial = 2.37
changed = 3.38
(changed/initial) - 1
0.4261603375527425

聯(lián)邦預算增長 42.6% 遠高于聯(lián)邦雇員增長 1.74%朗涩。 實際上忽孽,聯(lián)邦雇員的數量增長速度遠遠低于美國人口。美國人口同期增長 9.21%谢床,從 2002 年的 2.8760 億人增加到 2012 年的 3.41 億兄一。

initial = 287.6
changed = 314.1
(changed/initial) - 1
0.09214186369958277

增長率可能是負值,表示某種值的下降识腿。 例如出革,美國的制造業(yè)就業(yè)崗位從 2002 年 的 1530 萬減少到 2012 年的 1190 萬,增長率為 -22.2%渡讼。

initial = 15.3
changed = 11.9
(changed/initial) - 1
-0.2222222222222222

年增長率是一年之內的某個數量的增長率骂束。 年增長率為 0.035,累計十年成箫,十年增長率為 0.41(即 41%)展箱。

1.035 * 1.035 * 1.035 * 1.035 * 1.035 * 1.035 * 1.035 * 1.035 * 1.035 * 1.035 - 1
0.410598760621121

相同的計算可以使用名稱和指數表達。

annual_growth_rate = 0.035
ten_year_growth_rate = (1 + annual_growth_rate) ** 10 - 1
ten_year_growth_rate
0.410598760621121

同樣蹬昌,十年的增長率可以用來計算等價的年增長率混驰。 下面,t是兩次測量值之間經過的年數皂贩。 下面計算過去 10 年聯(lián)邦支出的年增長率栖榨。

initial = 2.37
changed = 3.38
t = 10
(changed/initial) ** (1/t) - 1
0.03613617208346853

十年來的總增長率相當于每年增長 3.6%。

總之明刷,增長率g用來描述initial(初始值)和經過一段時間t之后的changed(變化值)的相對大小婴栽。 為了計算changed,使用指數來重復應用增長率g t次辈末。

initial * (1 + g) ** t

為了計算g愚争,計算總增長率的1/t次方并減一映皆。

(changed/initial) ** (1/t) - 1

調用表達式

調用表達式調用函數,這些函數是具名操作准脂。 函數名稱首先出現劫扒,然后是括號中的表達式。

abs(-12)
12
round(5 - 1.3)
4
max(2, 2 + 3, 4)
5

在這最后一個例子中狸膏,max函數在三個參數:2, 54上調用沟饥。圓括號內每個表達式的值被傳遞給函數,函數返回整個調用表達式的最終值湾戳。 max函數可以接受任意數量的參數并返回最大值贤旷。

一些函數默認是可用的,比如absround砾脑,但是大部分內置于 Python 語言的函數都存儲在一個稱為模塊的函數集合中幼驶。 導入語句用于訪問模塊,如mathoperator韧衣。

import math
import operator
math.sqrt(operator.add(4, 5))
3.0

可以使用+**運算符來表達等價的表達式盅藻。

(4 + 5) ** 0.5
3.0

運算符和調用表達式可以在表達式中一起使用。 兩個值之間的百分比差異用于比較一些值畅铭,它們明顯既不是initial也不是changed氏淑。 例如,2014 年硕噩,佛羅里達農場生產了 27.2 億個蛋假残,而愛荷華州農場生產了 162.5 億個雞蛋 [1]。 百分比差值是數值之差的絕對值的 100 倍炉擅,再除以它們的平均值辉懒。 在這種情況下,差值大于平均值谍失,所以百分比差異大于 100眶俩。

[1] http://quickstats.nass.usda.gov/

florida = 2.72
iowa = 16.25
100*abs(florida-iowa)/((florida+iowa)/2)
142.6462836056932

學習不同函數的行為,是學習編程語言的重要組成部分快鱼。 Jupyter 筆記本可以幫助你記住不同函數的名稱和效果仿便。 編輯代碼單元格時,在輸入名稱的開頭之后按 Tab 鍵攒巍,來顯示補全該名稱的方式列表。 例如荒勇,在math后按 Tab 鍵柒莉,來查看math模塊中所有可用函數。 打字將縮小選項列表的范圍沽翔。 為了了解函數的更多信息兢孝,請在它的名稱之后放置一個?窿凤。 例如跨蟹,輸入math.log將顯示math模塊中log函數的描述夯秃。

math.log?
log(x[, base])

Return the logarithm of x to the given base.
If the base not specified, returns the natural logarithm (base e) of x.

示例調用中的方括號表示參數是可選的色建。 也就是說国撵,可以用一個或兩個參數來調用log走越。

math.log(16, 2)
4.0
math.log(16)/math.log(2)
4.0

Python 的內建函數列表非常長谆构,包含了許多在數據科學應用中不需要的函數熬尺。 math模塊中的數學函數列表同樣很長揭措。 本文將在上下文中介紹最重要的函數躬充,而不是期望讀者記住或理解這些列表麻裳。

示例

1869 年口蝠,一位名叫查爾斯·約瑟夫·米納德(Charles Joseph Minard)的法國土木工程師,創(chuàng)造了一個圖表津坑,仍被認為是有史以來最偉大的圖表之一妙蔗。 它顯示了拿破侖軍隊從莫斯科撤退期間的損失。 1812 年疆瑰,拿破侖開始征服俄羅斯眉反,他的軍隊中有超過 35 萬人。 他們確實到達了莫斯科穆役,但是沿路一直受到損失的困擾寸五。 俄國軍隊不斷撤退到俄羅斯深處,故意焚燒田野耿币,并在撤退時摧毀村莊梳杏。 這使法國軍隊在俄羅斯冬季來臨之時,沒有食物或避難所淹接。法國軍隊在莫斯科沒有取得決定性的勝利就撤退了十性。 之后天氣變冷,死了更多的人塑悼。 回來的人還不到一萬劲适。

image

Minard 的地圖

這個圖表繪制在東歐地圖上。 它始于左端的波蘭-俄羅斯邊界厢蒜。 淺棕色的條形表示拿破侖的軍隊正在向莫斯科進軍霞势,黑色的條形代表軍隊的撤退。 在圖表的每個點上斑鸦,軍隊的寬度與軍隊中士兵的數量成正比愕贡。在圖表的底部,Minard 包括了回程的溫度巷屿。

注意當軍隊撤退時固以,黑色條形變窄。 渡過貝爾齊納河是個特別的災難攒庵,你能在圖表上看到嗎嘴纺?

由于其簡單和有力,這個圖標是出色的浓冒。 Minard 展示了六個變量:

  • 士兵的數量
  • 行軍的方向
  • 位置的經緯度
  • 回程的溫度
  • 十一月和十二月的具體日期的位置

Tufte 說 Minard 的圖是“可能是有史以來最好的統(tǒng)計圖表”栽渴。

這里是 Minard 數據的一個子集,取自 Leland Wilkinson 的 The Grammar of Graphics稳懒。

image

Minard 的子集

每一行表示特定位置的軍隊狀態(tài)闲擦。 列以度為單位展示經度和緯度,位置的名稱场梆,軍隊是前進還是撤退墅冷,以及估計的人數。

在這個表格中或油,連續(xù)兩個地點之間的人數的最大變化是在莫斯科撤退的時候寞忿,也是最大的百分比變化。

moscou = 100000
wixma = 55000
wixma - moscou
-45000
(wixma - moscou)/moscou
-0.45

在莫斯科的戰(zhàn)斗中顶岸,人數下降了 45%腔彰。 換句話說,進入莫斯科的拿破侖的軍隊中辖佣,有幾乎一半的人沒有繼續(xù)前進霹抛。

正如你在圖表中看到的,Moiodexno 非常接近軍隊出發(fā)位置 Kowno卷谈。 在前進期間進入 Smolensk 的人中杯拐,只有不到 10% 的人在返回的途中到達了 Moiodexno。

smolensk_A = 145000
moiodexno = 12000
(moiodexno - smolensk_A)/smolensk_A
-0.9172413793103448

是的世蔗,只要使用沒有名稱的數字就可以做這些計算端逼。 但是這些名稱使得閱讀代碼和解釋結果變得更容易。

值得注意的是凸郑,更大的絕對變化并不總是對應更大的百分比變化裳食。

在前進期間,從 Smolensk 到 Dorogobouge 的絕對損失是 5000 人芙沥,而撤退期間诲祸,從 Smolensk 到 Orscha 的相應損失是 4000 人。

然而而昨,Smolensk 和 Orscha 之間的百分比變化要大得多救氯,因為,在撤退期間歌憨,Smolensk 的人員總數要小得多着憨。

dorogobouge = 140000
smolensk_R = 24000
orscha = 20000
abs(dorogobouge - smolensk_A)
5000
abs(dorogobouge - smolensk_A)/smolensk_A
0.034482758620689655
abs(orscha - smolensk_R)
4000
abs(orscha - smolensk_R)/smolensk_R
0.16666666666666666
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市务嫡,隨后出現的幾起案子甲抖,更是在濱河造成了極大的恐慌漆改,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件准谚,死亡現場離奇詭異挫剑,居然都是意外死亡,警方通過查閱死者的電腦和手機柱衔,發(fā)現死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門樊破,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人唆铐,你說我怎么就攤上這事哲戚。” “怎么了艾岂?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵顺少,是天一觀的道長。 經常有香客問我澳盐,道長祈纯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任叼耙,我火速辦了婚禮腕窥,結果婚禮上,老公的妹妹穿的比我還像新娘筛婉。我一直安慰自己簇爆,他們只是感情好,可當我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布爽撒。 她就那樣靜靜地躺著入蛆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪硕勿。 梳的紋絲不亂的頭發(fā)上哨毁,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天,我揣著相機與錄音源武,去河邊找鬼扼褪。 笑死,一個胖子當著我的面吹牛粱栖,可吹牛的內容都是我干的话浇。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼闹究,長吁一口氣:“原來是場噩夢啊……” “哼幔崖!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤赏寇,失蹤者是張志新(化名)和其女友劉穎吉嫩,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體嗅定,經...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡率挣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了露戒。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡捶箱,死狀恐怖智什,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情丁屎,我是刑警寧澤荠锭,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站晨川,受9級特大地震影響证九,放射性物質發(fā)生泄漏。R本人自食惡果不足惜共虑,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一愧怜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧妈拌,春花似錦拥坛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至培愁,卻和暖如春著摔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背定续。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工谍咆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人香罐。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓卧波,卻偏偏與公主長得像,于是被迫代替她去往敵國和親庇茫。 傳聞我的和親對象是個殘疾皇子港粱,可洞房花燭夜當晚...
    茶點故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內容