Python 和 Pandas 數(shù)據(jù)分析教程
原文:Data Analysis with Python and Pandas Tutorial Introduction
譯者:飛龍
協(xié)議:CC BY-NC-SA 4.0
大家好斥废,歡迎閱讀 Python 和 Pandas 數(shù)據(jù)分析系列教程宇攻。 Pandas 是一個 Python 模塊鸠儿,Python 是我們要使用的編程語言苍柏。Pandas 模塊是一個高性能呛占,高效率嫌松,高水平的數(shù)據(jù)分析庫皂冰。
它的核心就像操作一個電子表格的無頭版本贿讹,比如 Excel吠裆。你使用的大多數(shù)數(shù)據(jù)集將是所謂的數(shù)據(jù)幀(DataFrame
)伐谈。你可能已經(jīng)熟悉這個術(shù)語,它也用于其他語言试疙,但是如果沒有诵棵,數(shù)據(jù)幀通常就像電子表格一樣,擁有列和行祝旷,這就是它了履澳!從這里開始,我們可以利用 Pandas 以閃電般的速度操作我們的數(shù)據(jù)集怀跛。
Pandas 還與許多其他數(shù)據(jù)分析庫兼容距贷,如用于機(jī)器學(xué)習(xí)的 Scikit-Learn,用于圖形的 Matplotlib吻谋,NumPy忠蝗,因為它使用 NumPy ,以及其他漓拾。這些是非常強(qiáng)大和寶貴的阁最。如果你發(fā)現(xiàn)自己使用 Excel 或者一般電子表格來執(zhí)行各種計算任務(wù),那么他們可能需要一分鐘或者一小時來運(yùn)行骇两,Pandas 將會改變你的生活速种。我甚至已經(jīng)看到機(jī)器學(xué)習(xí)的版本,如 K-Means 聚類在 Excel 上完成低千。這真的很酷配阵,但是我的 Python 會為你做得更快,這也將使你對參數(shù)要求更嚴(yán)格,擁有更大的數(shù)據(jù)集闸餐,并且能夠完成更多的工作饱亮。
還有一個好消息。你可以很容易加載和輸出xls
或xlsx
格式的文件舍沙,所以近上,即使你的老板想用舊的方式來查看,他們也可以拂铡。Pandas 還可以兼容文本文件壹无,csv
,hdf
文件感帅,xml
斗锭,html
等等,其 IO 非常強(qiáng)大失球。
如果你剛剛?cè)腴T Python岖是,那么你應(yīng)該可以繼續(xù)學(xué)習(xí),而不必精通 Python实苞,這甚至可以讓你入門 Python 豺撑。最重要的是,如果你有問題黔牵,問問他們聪轿!如果你為每一個困惑的領(lǐng)域?qū)ふ掖鸢福榇俗龊妹考禄郑敲醋罱K你會有一個完整的認(rèn)識陆错。你的大部分問題都可以通過 Google 解決。不要害怕 Google 你的問題金赦,它不會嘲笑你音瓷,我保證。我仍然 Google 了我的很多目標(biāo)夹抗,看看是否有人有一些示例代碼外莲,做了我想做的事情,所以不要僅僅因為你這樣做了兔朦,而覺得你是個新手。
如果我還沒有把 Pandas 推銷給你磨确,那么電梯演講就是:電子表格式數(shù)據(jù)的閃電般的數(shù)據(jù)分析沽甥,具有非常強(qiáng)大的輸入/輸出機(jī)制,可以處理多種數(shù)據(jù)類型乏奥,甚至可以轉(zhuǎn)換數(shù)據(jù)類型摆舟。
好的,你被推銷了。現(xiàn)在讓我們獲取 Pandas恨诱!首先媳瞪,我將假設(shè)有些人甚至還沒有 Python。到目前為止照宝,最簡單的選擇是使用預(yù)編譯的 Python 發(fā)行版蛇受,比如 ActivePython,它是個快速簡單的方式厕鹃,將數(shù)據(jù)科學(xué)所需的所有包和依賴關(guān)系都集中在一起兢仰,而不需要一個接一個安裝它們,特別是在 64 位 Windows 上剂碴。我建議獲取最新版本的 64 位 Python把将。僅在這個系列中,我們使用 Pandas 忆矛,它需要 Numpy察蹲。我們還將使用 Matplotlib 和 Scikit-Learn,所有這些都是 ActivePython 自帶的催训,預(yù)先編譯和優(yōu)化的 MKL洽议。你可以從這里下載一個配置完整的 Python 發(fā)行版。
如果你想手動安裝 Python瞳腌,請轉(zhuǎn)到Python.org
绞铃,然后下載 Python 3+ 或更高版本。不要僅僅獲取2.X
嫂侍。記下你下載的位版本儿捧。因為你的操作系統(tǒng)是 64 位的,這并是你的 Python 版本挑宠,默認(rèn)總是 32 位菲盾。選擇你想要的。 64 位可能有點(diǎn)頭疼各淀,所以如果你是新手懒鉴,我不會推薦它,但 64 位是數(shù)據(jù)科學(xué)的理想選擇碎浇,所以你不會被鎖定在最大 2GB 的 RAM 上临谱。如果你想裝 64 位,查看pip
安裝教程可能有幫助奴璃,其中介紹了如何處理常規(guī)安裝以及更棘手的 64 位軟件包悉默。如果你使用 32 位,那么現(xiàn)在不用擔(dān)心這個教程苟穆。
所以你已經(jīng)安裝了 Python抄课。接下來唱星,轉(zhuǎn)到你的終端或cmd.exe
,然后鍵入:pip install pandas
跟磨。你有沒有得到pip is not a recognized command
或類似的東西间聊?沒問題,這意味著pip
不在你的PATH
中抵拘。pip
是一個程序哎榴,但是你的機(jī)器不知道它在哪里,除非它在你的PATH
中仑濒。如果你愿意叹话,你可以搜索如何添加一些東西到你的PATH
中,但是你總是可以顯式提供你想要執(zhí)行的程序的路徑墩瞳。例如驼壶,在 Windows 上,Python 的pip
位于C:/Python34/Scripts/pip
中喉酌。 Python34
的意思是 Python 3.4热凹。如果你擁有 Python 3.6,那么你需要使用Python36
泪电,以此類推般妙。
因此,如果常規(guī)的pip install pandas
不起作用相速,那么你可以執(zhí)行C:/Python34/Scripts/pip install pandas
碟渺。
到了這里,人們爭論的另一個重點(diǎn)是他們選擇的編輯器突诬。編輯器在事物的宏觀層面中并不重要苫拍。你應(yīng)該嘗試多個編輯器巷挥,并選擇最適合你的編輯器绘迁。無論哪個,只要你感到舒適伦乔,而且你的工作效率很高蔬捷,這是最重要的垄提。一些雇主也會迫使你最終使用編輯器 X,Y 或 Z周拐,所以你可能不應(yīng)該依賴編輯器功能铡俐。因此,我更喜歡簡單的 IDLE妥粟,這就是我將用于編程的東西高蜂。再次,你可以在 Wing罕容,emacs备恤,Nano,Vim锦秒,PyCharm露泊,IPython 中編程,你可以隨便選一個旅择。要打開 IDLE惭笑,只需訪問開始菜單,搜索 IDLE生真,然后選擇它沉噩。在這里,File > New
柱蟀,砰的一下川蒙,你就有了帶高亮的文本編輯器和其他一些小東西。我們將在進(jìn)行中介紹一些這些次要的事情长已。
現(xiàn)在畜眨,無論你使用哪種編輯器,都可以打開它术瓮,讓我們編寫一些簡單的代碼來查看數(shù)據(jù)幀康聂。
通常,DataFrame
最接近 Python Dictionary
數(shù)據(jù)結(jié)構(gòu)胞四。如果你不熟悉字典恬汁,這里有一個教程。我將在視頻中注明類似的東西辜伟,并且在描述中氓侧,以及在PythonProgramming.net
上的文本版教程中有鏈接。
首先游昼,我們來做一些簡單的導(dǎo)入:
import pandas as pd
import datetime
import pandas.io.data as web
在這里甘苍,我們將pandas
導(dǎo)入為pd
。 這只是導(dǎo)入pandas
模塊時使用的常用標(biāo)準(zhǔn)烘豌。 接下來载庭,我們導(dǎo)入datetime
,我們稍后將使用它來告訴 Pandas 一些日期廊佩,我們想要拉取它們之間的數(shù)據(jù)囚聚。 最后,我們將pandas.io.data
導(dǎo)入為web
标锄,因為我們將使用它來從互聯(lián)網(wǎng)上獲取數(shù)據(jù)顽铸。 接下來:
start = datetime.datetime(2010, 1, 1)
end = datetime.datetime(2015, 8, 22)
在這里,我們創(chuàng)建start
和end
變量料皇,這些變量是datetime
對象谓松,獲取 2010 年 1 月 1 日到 2015 年 8 月 22 日的數(shù)據(jù)⌒茄梗現(xiàn)在,我們可以像這樣創(chuàng)建數(shù)據(jù)幀:
df = web.DataReader("XOM", "yahoo", start, end)
這從雅虎財經(jīng) API 獲取 Exxon 的數(shù)據(jù)鬼譬,存儲到我們的df
變量娜膘。 將你的數(shù)據(jù)幀命名為df
不是必需的,但是它頁是用于 Pandas 的非常主流的標(biāo)準(zhǔn)优质。 它只是幫助人們立即識別活動數(shù)據(jù)幀竣贪,而無需追溯代碼。
所以這給了我們一個數(shù)據(jù)幀巩螃,我們怎么查看它演怎? 那么,可以打印它避乏,就像這樣:
print(df)
所以這是很大一個空間爷耀。 數(shù)據(jù)集的中間被忽略,但仍然是大量輸出淑际。 相反畏纲,大多數(shù)人只會這樣做:
print(df.head())
輸出:
Open High Low Close Volume Adj Close
Date
2010-01-04 68.720001 69.260002 68.190002 69.150002 27809100 59.215446
2010-01-05 69.190002 69.449997 68.800003 69.419998 30174700 59.446653
2010-01-06 69.449997 70.599998 69.339996 70.019997 35044700 59.960452
2010-01-07 69.900002 70.059998 69.419998 69.800003 27192100 59.772064
2010-01-08 69.690002 69.750000 69.220001 69.519997 24891800 59.532285
這打印了數(shù)據(jù)幀的前 5 行,并且對于調(diào)試很有用春缕,只查看了數(shù)據(jù)幀的外觀盗胀。 當(dāng)你執(zhí)行分析等,看看你想要的東西是否實際發(fā)生了锄贼,就很有用票灰。 不過,我們稍后會深入它宅荤。
我們可以在這里停止介紹屑迂,但還有一件事:數(shù)據(jù)可視化。 我之前說過冯键,Pandas 和其他模塊配合的很好惹盼,Matplotlib 就是其中之一。 讓我們來看看惫确! 打開你的終端或cmd.exe
手报,并執(zhí)行pip install matplotlib
。 你安裝完 Pandas改化,我確信你應(yīng)該已經(jīng)獲取了它掩蛤,但我們要證實一下。 現(xiàn)在陈肛,在腳本的頂部揍鸟,和其他導(dǎo)入一起,添加:
import matplotlib.pyplot as plt
from matplotlib import style
style.use('fivethirtyeight')
Pyplot 是 matplotlib 的基本繪圖模塊句旱。 Style 幫助我們快速美化圖形阳藻,style.use
讓我們選擇風(fēng)格晰奖。 有興趣了解 Matplotlib 的更多信息嗎? 查看 Matplotlib 的深入系列教程腥泥!
接下來畅涂,在我們的print(df.head())
下方,我們可以執(zhí)行如下操作:
df['High'].plot()
plt.legend()
plt.show()
https://pythonprogramming.net/static/images/pandas/pandas-graph-example.png
很酷道川! 這里有個 pandas 的快速介紹,但一點(diǎn)也不可用立宜。 在這個系列中冒萄,我們將會涉及更多 Pandas 的基礎(chǔ)知識,然后轉(zhuǎn)到導(dǎo)航和處理數(shù)據(jù)幀橙数。 從這里開始尊流,我們將更多地介紹可視化,多種數(shù)據(jù)格式的輸入和輸出灯帮,基本和進(jìn)階數(shù)據(jù)分析和操作崖技,合并和組合數(shù)據(jù)幀,重復(fù)取樣等等钟哥。
如果你迷茫迎献,困惑,或需要澄清腻贰,請不要猶豫吁恍,給對應(yīng)的視頻提問。
二播演、Pandas 基礎(chǔ)
在這個 Python 和 Pandas 數(shù)據(jù)分析教程中冀瓦,我們將弄清一些 Pandas 的基礎(chǔ)知識。 加載到 Pandas 數(shù)據(jù)幀之前写烤,數(shù)據(jù)可能有多種形式翼闽,但通常需要是以行和列組成的數(shù)據(jù)集。 所以也許是這樣的字典:
web_stats = {'Day':[1,2,3,4,5,6],
'Visitors':[43,34,65,56,29,76],
'Bounce Rate':[65,67,78,65,45,52]}
我們可以將這個字典轉(zhuǎn)換成數(shù)據(jù)幀洲炊,通過這樣:
import pandas as pd
web_stats = {'Day':[1,2,3,4,5,6],
'Visitors':[43,34,65,56,29,76],
'Bounce Rate':[65,67,78,65,45,52]}
df = pd.DataFrame(web_stats)
現(xiàn)在我們可以做什么感局?之前看到,你可以通過這樣來查看簡單的起始片段:
print(df.head())
Bounce Rate Day Visitors
0 65 1 43
1 67 2 34
2 78 3 65
3 65 4 56
4 45 5 29
你也可以查看后幾行选浑。為此蓝厌,你需要這樣做:
print(df.tail())
Bounce Rate Day Visitors
1 67 2 34
2 78 3 65
3 65 4 56
4 45 5 29
5 52 6 76
最后,你也可以傳入頭部和尾部數(shù)量古徒,像這樣:
print(df.tail(2))
Bounce Rate Day Visitors
4 45 5 29
5 52 6 76
你可以在這里看到左邊有這些數(shù)字拓提,0,1,2,3,4,5
等等,就像行號一樣隧膘。 這些數(shù)字實際上是你的“索引”代态。 數(shù)據(jù)幀的索引是數(shù)據(jù)相關(guān)寺惫,或者數(shù)據(jù)按它排序的東西。 一般來說蹦疑,這將是連接所有數(shù)據(jù)的變量西雀。 這里,我們從來沒有為此目的定義任何東西歉摧,知道這個變量是什么艇肴,對于 Pandas 是個挑戰(zhàn)。 因此叁温,當(dāng)你沒有定義索引時再悼,Pandas 會像這樣為你生成一個。 現(xiàn)在看數(shù)據(jù)集膝但,你能看到連接其他列的列嗎冲九?
Day
列適合這個東西! 一般來說跟束,如果你有任何日期數(shù)據(jù)莺奸,日期將成為“索引”,因為這就是所有數(shù)據(jù)點(diǎn)的關(guān)聯(lián)方式冀宴。 有很多方法可以識別索引灭贷,更改索引等等。 我們將在這里介紹一些花鹅。 首先氧腰,在任何現(xiàn)有的數(shù)據(jù)幀上,我們可以像這樣設(shè)置一個新的索引:
df.set_index('Day', inplace=True)
輸出:
Bounce Rate Visitors
Day
1 65 43
2 67 34
3 78 65
4 65 56
5 45 29
現(xiàn)在你可以看到這些行號已經(jīng)消失了刨肃,同時也注意到Day
比其他列標(biāo)題更低古拴,這是為了表示索引。 有一點(diǎn)需要注意的是inplace = True
的使用真友。 這允許我們原地修改數(shù)據(jù)幀黄痪,意味著我們實際上修改了變量本身。 沒有inplace = True
盔然,我們需要做一些事情:
df = df.set_index('Day')
你也可以設(shè)置多個索引桅打,但這是以后的更高級的主題。 你可以很容易做到這一點(diǎn)愈案,但它的原因相當(dāng)合理挺尾。
一旦你有了合理的索引,是一個日期時間或數(shù)字站绪,那么它將作為一個 X 軸遭铺。 如果其他列也是數(shù)值數(shù)據(jù),那么你可以輕松繪圖。 就像我們之前做的那樣魂挂,繼續(xù)并執(zhí)行:
import matplotlib.pyplot as plt
from matplotlib import style
style.use('fivethirtyeight')
然后甫题,在底部,你可以繪圖涂召。 還記得我們之前引用了特定的列嘛坠非?也許你注意到了,但是我們可以像這樣果正,引用數(shù)據(jù)幀中的特定項目:
print(df['Visitors'])
Day
1 43
2 34
3 65
4 56
5 29
6 76
Name: Visitors, dtype: int64
你也可以像對象一樣引用數(shù)據(jù)幀的部分炎码,只要沒有空格,就可以這樣做:
print(df.Visitors)
Day
1 43
2 34
3 65
4 56
5 29
6 76
Name: Visitors, dtype: int64
所以我們可以像這樣繪制單列:
df['Visitors'].plot()
plt.show()
我們也可以繪制整個數(shù)據(jù)幀秋泳。 只要數(shù)據(jù)是規(guī)范化的或者在相同的刻度上辅肾,效果會很好。 這是一個例子:
df.plot()
plt.show()
注意圖例如何自動添加轮锥。 你可能會喜歡的另一個很好的功能是,圖例也自動為實際繪制的直線讓路要尔。 如果你是 Python 和 Matplotlib 的新手舍杜,這可能對你來說并不重要,但這不是一個正常的事情赵辕。
最后既绩,在我們離開之前茧妒,你也可以一次引用多個列隘梨,就像這樣(我們只有兩列苹熏,但是多列相同):
print(df[['Visitors','Bounce Rate']])
所以這是括起來的列標(biāo)題列表氓拼。 你也可以繪制這個秋冰。
這些是一些方法宪巨,你可以直接與數(shù)據(jù)幀進(jìn)行交互值戳,引用數(shù)據(jù)框的各個方面吏饿,帶有一個示例锣光,繪制了這些特定的方面笆怠。
三、IO 基礎(chǔ)
歡迎閱讀 Pandas 和 Python 數(shù)據(jù)分析第三部分誊爹。在本教程中蹬刷,我們將開始討論 Pandas IO 即輸入/輸出,并從一個實際的用例開始频丘。為了得到充分的實踐办成,一個非常有用的網(wǎng)站是 Quandl。 Quandl 包含大量的免費(fèi)和付費(fèi)數(shù)據(jù)源搂漠。這個站點(diǎn)的好處在于數(shù)據(jù)通常是標(biāo)準(zhǔn)化的迂卢,全部在一個地方,提取數(shù)據(jù)的方法是一樣的。如果你使用的是 Python冷守,并且通過它們的簡單模塊訪問 Quandl 數(shù)據(jù)刀崖,那么數(shù)據(jù)將自動以數(shù)據(jù)幀返回。出于本教程的目的拍摇,我們將僅僅出于學(xué)習(xí)的目的而手動下載一個 CSV 文件亮钦,因為并不是每個數(shù)據(jù)源都會有一個完美的模塊用于提取數(shù)據(jù)集。
假設(shè)我們有興趣充活,在德克薩斯州的奧斯汀購買或出售房屋蜂莉。那里的郵政編碼是 77006。我們可以訪問當(dāng)?shù)氐姆吭辞鍐位炻眩纯茨壳暗膬r格是多少映穗,但這并不能真正為我們提供任何真實的歷史信息,所以我們只是試圖獲得一些數(shù)據(jù)幕随。讓我們來查詢“房屋價值指數(shù) 77006”蚁滋。果然,我們可以在這里看到一個索引赘淮。有頂層辕录,中層,下層梢卸,三居室走诞,等等。比方說蛤高,當(dāng)然蚣旱,我們有一個三居室的房子。我們來檢查一下戴陡。原來 Quandl 已經(jīng)提供了圖表塞绿,但是我們還是要抓取數(shù)據(jù)集,制作自己的圖表恤批,或者做一些其他的分析位隶。訪問“下載”,并選擇 CSV开皿。Pandas 的 IO 兼容 csv涧黄,excel 數(shù)據(jù),hdf赋荆,sql笋妥,json,msgpack窄潭,html春宣,gbq,stata,剪貼板和 pickle 數(shù)據(jù)月帝,并且列表不斷增長躏惋。查看 IO 工具文檔的當(dāng)前列表。將該 CSV 文件移動到本地目錄(你正在使用的目錄/這個.py
腳本所在的目錄)嚷辅。
以這個代碼開始簿姨,將 CSV 加載進(jìn)數(shù)據(jù)幀就是這樣簡單:
import pandas as pd
df = pd.read_csv('ZILL-Z77006_3B.csv')
print(df.head())
輸出:
Date Value
0 2015-06-30 502300
1 2015-05-31 501500
2 2015-04-30 500100
3 2015-03-31 495800
4 2015-02-28 492700
注意我們又沒有了合適的索引。我們可以首先這樣做來修復(fù):
df.set_index('Date', inplace = True)
現(xiàn)在簸搞,讓我們假設(shè)扁位,我們打算將它轉(zhuǎn)回 CSV,我們可以:
df.to_csv('newcsv2.csv')
我們僅僅有了一列趁俊,但是如果你有很多列域仇,并且僅僅打算轉(zhuǎn)換一列,你可以:
df['Value'].to_csv('newcsv2.csv')
要記住我們?nèi)绾卫L制多列寺擂,但是并不是所有列暇务。看看你能不能猜出如何保存多列怔软,但不是所有列般卑。
現(xiàn)在,讓我們讀取新的 CSV:
df = pd.read_csv('newcsv2.csv')
print(df.head())
輸出:
Date Value
0 2015-06-30 502300
1 2015-05-31 501500
2 2015-04-30 500100
3 2015-03-31 495800
4 2015-02-28 492700
該死爽雄,我們的索引又沒了! 這是因為 CSV 沒有像我們的數(shù)據(jù)幀那樣的“索引”屬性沐鼠。 我們可以做的是挚瘟,在導(dǎo)入時設(shè)置索引,而不是導(dǎo)入之后設(shè)置索引饲梭。 像這樣:
df = pd.read_csv('newcsv2.csv', index_col=0)
print(df.head())
輸出:
Value
Date
2015-06-30 502300
2015-05-31 501500
2015-04-30 500100
2015-03-31 495800
2015-02-28 492700
現(xiàn)在乘盖,我不了解你,但“價值”這個名字是毫無價值的憔涉。 我們可以改變這個嗎订框? 當(dāng)然,有很多方法來改變列名兜叨,一種方法是:
df.columns = ['House_Prices']
print(df.head())
輸出:
House_Prices
Date
2015-06-30 502300
2015-05-31 501500
2015-04-30 500100
2015-03-31 495800
2015-02-28 492700
下面穿扳,我們可以嘗試這樣保存為 CSV:
df.to_csv('newcsv3.csv')
如果你看看 CSV,你應(yīng)該看到它擁有標(biāo)題国旷。如果不想要標(biāo)題怎么辦呢矛物?沒問題!
df.to_csv('newcsv4.csv', header=False)
如果文件沒有標(biāo)題呢跪但?沒問題履羞!
df = pd.read_csv('newcsv4.csv', names = ['Date','House_Price'], index_col=0)
print(df.head())
輸出:
House_Price
Date
2015-06-30 502300
2015-05-31 501500
2015-04-30 500100
2015-03-31 495800
2015-02-28 492700
這些是IO的基本知識,在輸入和輸出時有一些選項。
一個有趣的事情是使用 Pandas 進(jìn)行轉(zhuǎn)換忆首。 所以爱榔,也許你是從 CSV 輸入數(shù)據(jù),但你真的希望在你的網(wǎng)站上糙及,將這些數(shù)據(jù)展示為 HTML详幽。 由于 HTML 是數(shù)據(jù)類型之一,我們可以將其導(dǎo)出為 HTML丁鹉,如下所示:
df.to_html('example.html')
現(xiàn)在我們有了 HTML 文件妒潭。打開它,然后你就有了 HTML 中的一個表格:
House_Prices | |
---|---|
Date | |
2015-06-30 | 502300 |
2015-05-31 | 501500 |
2015-04-30 | 500100 |
2015-03-31 | 495800 |
2015-02-28 | 492700 |
2015-01-31 | 493000 |
2014-12-31 | 494200 |
2014-11-30 | 490900 |
2014-10-31 | 486000 |
2014-09-30 | 479800 |
2014-08-31 | 473900 |
2014-07-31 | 467100 |
2014-06-30 | 461400 |
2014-05-31 | 455400 |
2014-04-30 | 450500 |
2014-03-31 | 450300 |
注意揣钦,這個表自動分配了dataframe
類雳灾。 這意味著你可以自定義 CSS 來處理數(shù)據(jù)幀特定的表!
當(dāng)我有用數(shù)據(jù)的 SQL 轉(zhuǎn)儲時冯凹,我特別喜歡使用 Pandas谎亩。 我傾向于將數(shù)據(jù)庫數(shù)據(jù)直接倒入 Pandas 數(shù)據(jù)幀中,執(zhí)行我想要執(zhí)行的操作宇姚,然后將數(shù)據(jù)顯示在圖表中匈庭,或者以某種方式提供數(shù)據(jù)。
最后浑劳,如果我們想重新命名其中一列阱持,該怎么辦? 之前魔熏,你已經(jīng)看到了如何命名所有列衷咽,但是也許你只是想改變一個列,而不必輸入所有的列蒜绽。 足夠簡單:
print(df.head())
df.rename(columns={'House_Price':'Prices'}, inplace=True)
print(df.head())
輸出:
Date House_Price
0 2015-06-30 502300
1 2015-05-31 501500
2 2015-04-30 500100
3 2015-03-31 495800
4 2015-02-28 492700
Date Prices
0 2015-06-30 502300
1 2015-05-31 501500
2 2015-04-30 500100
3 2015-03-31 495800
4 2015-02-28 492700
所以在這里镶骗,我們首先導(dǎo)入了無頭文件,提供了列名Date
和House_Price
躲雅。 然后鼎姊,我們決定,我們打算用Price
代替House_Price
相赁。 因此相寇,我們使用df.rename
,指定我們要重命名的列钮科,然后在字典形式中裆赵,鍵是原始名稱,值是新名稱跺嗽。 我們最終使用inplace = True
战授,以便修改原始對象页藻。
四、構(gòu)件數(shù)據(jù)集
在 Python 和 Pandas 數(shù)據(jù)分析系列教程的這一部分中植兰,我們將擴(kuò)展一些東西份帐。讓我們想想,我們是億萬富豪楣导,還是千萬富豪废境,但成為億萬富豪則更有趣,我們正在努力使我們的投資組合盡可能多樣化筒繁。我們希望擁有所有類型的資產(chǎn)類別噩凹,所以我們有股票,債券毡咏,也許是一個貨幣市場帳戶驮宴,現(xiàn)在我們正在尋找堅實的不動產(chǎn)。你們都看過廣告了嗎呕缭?你買了 60 美元的 CD堵泽,參加了 500 美元的研討會,你開始把你的 6 位數(shù)字投資到房地產(chǎn)恢总,對吧迎罗?
好吧,也許不是片仿,但是我們肯定要做一些研究纹安,并有一些購買房地產(chǎn)的策略。那么砂豌,什么統(tǒng)治了房價厢岂,我們是否需要進(jìn)行研究才能找到答案?一般來說奸鸯,不,你并不需要那么做可帽,我們知道這些因素娄涩。房價的因素受經(jīng)濟(jì),利率和人口統(tǒng)計的影響映跟。這是房地產(chǎn)價格總體上的三大影響⌒罴穑現(xiàn)在當(dāng)然,如果你買土地努隙,其他的事情很重要球恤,它的水平如何,我們是否需要在土地上做一些工作荸镊,才能真正奠定基礎(chǔ)咽斧,如何排水等等堪置。那么我們還有更多的因素,比如屋頂张惹,窗戶舀锨,暖氣/空調(diào),地板宛逗,地基等等坎匿。我們可以稍后考慮這些因素,但首先我們要從宏觀層面開始雷激。你會看到我們的數(shù)據(jù)集在這里膨脹得有多快替蔬,它會爆炸式增長。
所以屎暇,我們的第一步是收集數(shù)據(jù)承桥。 Quandl 仍然是良好的起始位置,但是這一次讓我們自動化數(shù)據(jù)抓取恭垦。我們將首先抓取 50 個州的住房數(shù)據(jù)快毛,但是我們也試圖收集其他數(shù)據(jù)。我們絕對不想手動抓取這個數(shù)據(jù)番挺。首先唠帝,如果你還沒有帳戶,你需要得到一個帳戶玄柏。這將給你一個 API 密鑰和免費(fèi)數(shù)據(jù)的無限的 API 請求肠阱,這真棒。
一旦你創(chuàng)建了一個賬戶氓扛,訪問your account / me
算墨,不管他們這個時候叫什么,然后找到標(biāo)有 API 密鑰的部分徘意。這是你所需的密鑰苔悦。接下來,我們要獲取 Quandl 模塊椎咧。我們實際上并不需要模塊來生成請求玖详,但它是一個非常小的模塊,他能給我們帶來一些小便利勤讽,所以不妨試試蟋座。打開你的終端或cmd.exe
并且執(zhí)行pip install quandl
(再一次,如果pip
不能識別脚牍,記得指定pip
的完整路徑)向臀。
接下來,我們做好了開始的準(zhǔn)備诸狭,打開一個新的編輯器券膀。開始:
import Quandl
# Not necessary, I just do this so I do not show my API key.
api_key = open('quandlapikey.txt','r').read()
df = Quandl.get("FMAC/HPI_TX", authtoken=api_key)
print(df.head())
如果你愿意的話君纫,你可以只存儲你的密鑰的純文本版本,我只隱藏了我的密鑰三娩,因為它是我發(fā)布的教程庵芭。這是我們需要做的,來獲得德克薩斯州的房價指數(shù)雀监。我們抓取的實際指標(biāo)可以在任何頁面上找到双吆,無論你什么時候訪問,只要在網(wǎng)站上點(diǎn)擊你使用的庫会前,我們這里是 Python好乐,然后需要輸入的查詢就會彈出。
隨著你的數(shù)據(jù)科學(xué)事業(yè)的發(fā)展瓦宜,你將學(xué)習(xí)到各種常數(shù)蔚万,因為人們是合乎邏輯和合理的。我們這里临庇,我們需要獲取所有州的數(shù)據(jù)反璃。我們?nèi)绾巫龅侥兀课覀兪欠裥枰謩幼ト∶總€指標(biāo)假夺?不淮蜈,看看這個代碼,我們看到FMAC/HPI_TX
已卷。我們可以很容易地把這個解碼為FMAC = Freddie Mac
梧田。 HPI = House Price Index
(房價指數(shù))。TX
是德克薩斯州侧蘸,它的常用兩字母縮寫裁眯。從這里,我們可以安全地假設(shè)所有的代碼都是這樣構(gòu)建的讳癌,所以現(xiàn)在我們只需要一個州縮寫的列表穿稳。我們搜索它,作出選擇晌坤,就像這個 50 個州的列表逢艘。怎么辦?
我們可以通過多種方式提取這些數(shù)據(jù)泡仗。這是一個 Pandas 教程埋虹,所以如果我們可以 Pandas 熊貓猜憎,我們就這樣娩怎。讓我們來看看 Pandas 的read_html
。它不再被稱為“實驗性”的胰柑,但我仍然會將其標(biāo)記為實驗性的截亦。其他 IO 模塊的標(biāo)準(zhǔn)和質(zhì)量非常高并且可靠爬泥。read_html
并不是很好,但我仍然說這是非常令人印象深刻有用的代碼崩瓤,而且很酷袍啡。它的工作方式就是簡單地輸入一個 URL,Pandas 會從表中將有價值的數(shù)據(jù)提取到數(shù)據(jù)幀中却桶。這意味著境输,與其他常用的方法不同,read_html
最終會讀入一些列數(shù)據(jù)幀颖系。這不是唯一不同點(diǎn)嗅剖,但它是不同的。首先嘁扼,為了使用read_html
信粮,我們需要html5lib
。打開cmd.exe
或你的終端趁啸,并執(zhí)行:pip install html5lib
∏吭担現(xiàn)在,我們可以做我們的第一次嘗試:
fiddy_states = pd.read_html('https://simple.wikipedia.org/wiki/List_of_U.S._states')
print(fiddy_states)
它的輸出比我要在這里發(fā)布的更多不傅,但你明白了旅掂。 這些數(shù)據(jù)中至少有一部分是我們想要的,看起來第一個數(shù)據(jù)幀是一個很好的開始蛤签。 那么讓我們執(zhí)行:
print(fiddy_states[0])
0 1 2 3
0 Abbreviation State name Capital Became a state
1 AL Alabama Montgomery December 14, 1819
2 AK Alaska Juneau January 3, 1959
3 AZ Arizona Phoenix February 14, 1912
4 AR Arkansas Little Rock June 15, 1836
5 CA California Sacramento September 9, 1850
6 CO Colorado Denver August 1, 1876
7 CT Connecticut Hartford January 9, 1788
8 DE Delaware Dover December 7, 1787
9 FL Florida Tallahassee March 3, 1845
10 GA Georgia Atlanta January 2, 1788
11 HI Hawaii Honolulu August 21, 1959
12 ID Idaho Boise July 3, 1890
13 IL Illinois Springfield December 3, 1818
14 IN Indiana Indianapolis December 11, 1816
15 IA Iowa Des Moines December 28, 1846
16 KS Kansas Topeka January 29, 1861
17 KY Kentucky Frankfort June 1, 1792
18 LA Louisiana Baton Rouge April 30, 1812
19 ME Maine Augusta March 15, 1820
20 MD Maryland Annapolis April 28, 1788
21 MA Massachusetts Boston February 6, 1788
22 MI Michigan Lansing January 26, 1837
23 MN Minnesota Saint Paul May 11, 1858
24 MS Mississippi Jackson December 10, 1817
25 MO Missouri Jefferson City August 10, 1821
26 MT Montana Helena November 8, 1889
27 NE Nebraska Lincoln March 1, 1867
28 NV Nevada Carson City October 31, 1864
29 NH New Hampshire Concord June 21, 1788
30 NJ New Jersey Trenton December 18, 1787
31 NM New Mexico Santa Fe January 6, 1912
32 NY New York Albany July 26, 1788
33 NC North Carolina Raleigh November 21, 1789
34 ND North Dakota Bismarck November 2, 1889
35 OH Ohio Columbus March 1, 1803
36 OK Oklahoma Oklahoma City November 16, 1907
37 OR Oregon Salem February 14, 1859
38 PA Pennsylvania Harrisburg December 12, 1787
39 RI Rhode Island Providence May 19, 1790
40 SC South Carolina Columbia May 23, 1788
41 SD South Dakota Pierre November 2, 1889
42 TN Tennessee Nashville June 1, 1796
43 TX Texas Austin December 29, 1845
44 UT Utah Salt Lake City January 4, 1896
45 VT Vermont Montpelier March 4, 1791
46 VA Virginia Richmond June 25, 1788
47 WA Washington Olympia November 11, 1889
48 WV West Virginia Charleston June 20, 1863
49 WI Wisconsin Madison May 29, 1848
50 WY Wyoming Cheyenne July 10, 1890
是的辞友,這看起來不錯,我們想要第零列震肮。所以称龙,我們要遍歷fiddy_states[0]
的第零列。 請記住戳晌,現(xiàn)在fiddy_states
是一個數(shù)幀列表鲫尊,而fiddy_states[0]
是第一個數(shù)據(jù)幀。 為了引用第零列沦偎,我們執(zhí)行fiddy_states[0][0]
疫向。 一個是列表索引,它返回一個數(shù)據(jù)幀豪嚎。 另一個是數(shù)據(jù)幀中的一列搔驼。 接下來,我們注意到第零列中的第一項是abbreviation
侈询,我們不想要它舌涨。 當(dāng)我們遍歷第零列中的所有項目時,我們可以使用[1:]
排除掉它扔字。 因此囊嘉,我們的縮寫列表是fiddy_states[0][0][1:]
温技,我們可以像這樣迭代:
for abbv in fiddy_states[0][0][1:]:
print(abbv)
AL
AK
AZ
AR
CA
CO
CT
DE
FL
GA
HI
ID
IL
IN
IA
KS
KY
LA
ME
MD
MA
MI
MN
MS
MO
MT
NE
NV
NH
NJ
NM
NY
NC
ND
OH
OK
OR
PA
RI
SC
SD
TN
TX
UT
VT
VA
WA
WV
WI
WY
完美! 現(xiàn)在扭粱,我們回憶這樣做的原因:我們正在試圖用州名縮寫建立指標(biāo)舵鳞,來獲得每個州的房價指數(shù)。 好的琢蛤,我們可以建立指標(biāo):
for abbv in fiddy_states[0][0][1:]:
#print(abbv)
print("FMAC/HPI_"+str(abbv))
FMAC/HPI_AL
FMAC/HPI_AK
FMAC/HPI_AZ
FMAC/HPI_AR
FMAC/HPI_CA
FMAC/HPI_CO
FMAC/HPI_CT
FMAC/HPI_DE
FMAC/HPI_FL
FMAC/HPI_GA
FMAC/HPI_HI
FMAC/HPI_ID
FMAC/HPI_IL
FMAC/HPI_IN
FMAC/HPI_IA
FMAC/HPI_KS
FMAC/HPI_KY
FMAC/HPI_LA
FMAC/HPI_ME
FMAC/HPI_MD
FMAC/HPI_MA
FMAC/HPI_MI
FMAC/HPI_MN
FMAC/HPI_MS
FMAC/HPI_MO
FMAC/HPI_MT
FMAC/HPI_NE
FMAC/HPI_NV
FMAC/HPI_NH
FMAC/HPI_NJ
FMAC/HPI_NM
FMAC/HPI_NY
FMAC/HPI_NC
FMAC/HPI_ND
FMAC/HPI_OH
FMAC/HPI_OK
FMAC/HPI_OR
FMAC/HPI_PA
FMAC/HPI_RI
FMAC/HPI_SC
FMAC/HPI_SD
FMAC/HPI_TN
FMAC/HPI_TX
FMAC/HPI_UT
FMAC/HPI_VT
FMAC/HPI_VA
FMAC/HPI_WA
FMAC/HPI_WV
FMAC/HPI_WI
FMAC/HPI_WY
我們已經(jīng)得到了指標(biāo)蜓堕,現(xiàn)在我們已經(jīng)準(zhǔn)備好提取數(shù)據(jù)幀了。 但是博其,一旦我們拿到他們俩滥,我們會做什么? 我們將使用 50 個獨(dú)立的數(shù)據(jù)幀贺奠? 聽起來像一個愚蠢的想法霜旧,我們需要一些方法來組合他們。 Pandas 背后的優(yōu)秀人才看到了這一點(diǎn)儡率,并為我們提供了多種組合數(shù)據(jù)幀的方法挂据。 我們將在下一個教程中討論這個問題。
五儿普、連接(concat)和附加數(shù)據(jù)幀
歡迎閱讀 Python 和 Pandas 數(shù)據(jù)分析系列教程第五部分崎逃。在本教程中,我們將介紹如何以各種方式組合數(shù)據(jù)幀眉孩。
在我們的房地產(chǎn)投資案例中个绍,我們希望使用房屋數(shù)據(jù)獲取 50 個數(shù)據(jù)幀,然后把它們?nèi)亢喜⒊梢粋€數(shù)據(jù)幀浪汪。我們這樣做有很多原因巴柿。首先,將這些組合起來更容易死遭,更有意義广恢,也會減少使用的內(nèi)存。每個數(shù)據(jù)幀都有日期和值列呀潭。這個日期列在所有數(shù)據(jù)幀中重復(fù)出現(xiàn)钉迷,但實際上它們應(yīng)該全部共用一個,實際上幾乎減半了我們的總列數(shù)钠署。
在組合數(shù)據(jù)幀時糠聪,你可能會考慮相當(dāng)多的目標(biāo)。例如谐鼎,你可能想“附加”到他們舰蟆,你可能會添加到最后,基本上就是添加更多的行∝裁纾或者,也許你想添加更多的列隔缀,就像我們的情況一樣题造。有四種主要的數(shù)據(jù)幀組合方式,我們現(xiàn)在開始介紹猾瘸。四種主要的方式是:連接(Concatenation)界赔,連接(Join),合并和附加牵触。我們將從第一種開始淮悼。這里有一些初始數(shù)據(jù)幀:
df1 = pd.DataFrame({'HPI':[80,85,88,85],
'Int_rate':[2, 3, 2, 2],
'US_GDP_Thousands':[50, 55, 65, 55]},
index = [2001, 2002, 2003, 2004])
df2 = pd.DataFrame({'HPI':[80,85,88,85],
'Int_rate':[2, 3, 2, 2],
'US_GDP_Thousands':[50, 55, 65, 55]},
index = [2005, 2006, 2007, 2008])
df3 = pd.DataFrame({'HPI':[80,85,88,85],
'Int_rate':[2, 3, 2, 2],
'Low_tier_HPI':[50, 52, 50, 53]},
index = [2001, 2002, 2003, 2004])
注意這些之間有兩個主要的變化。 df1
和df3
具有相同的索引揽思,但它們有一些不同的列袜腥。 df2
和df3
有不同的索引和一些不同的列。 通過連接(concat)钉汗,我們可以討論將它們結(jié)合在一起的各種方法羹令。 我們來試一下簡單的連接(concat):
concat = pd.concat([df1,df2])
print(concat)
HPI Int_rate US_GDP_Thousands
2001 80 2 50
2002 85 3 55
2003 88 2 65
2004 85 2 55
2005 80 2 50
2006 85 3 55
2007 88 2 65
2008 85 2 55
很簡單。 這兩者之間的主要區(qū)別僅僅是索引的延續(xù)损痰,但是它們共享同一列福侈。 現(xiàn)在他們已經(jīng)成為單個數(shù)據(jù)幀。 然而我們這里卢未,我們對添加列而不是行感到好奇肪凛。 當(dāng)我們將一些共有的和一些新列組合起來:
concat = pd.concat([df1,df2,df3])
print(concat)
HPI Int_rate Low_tier_HPI US_GDP_Thousands
2001 80 2 NaN 50
2002 85 3 NaN 55
2003 88 2 NaN 65
2004 85 2 NaN 55
2005 80 2 NaN 50
2006 85 3 NaN 55
2007 88 2 NaN 65
2008 85 2 NaN 55
2001 80 2 50 NaN
2002 85 3 52 NaN
2003 88 2 50 NaN
2004 85 2 53 NaN
不錯,我們有一些NaN
(不是數(shù)字)辽社,因為那個索引處不存在數(shù)據(jù)伟墙,但是我們所有的數(shù)據(jù)確實在這里。
這些就是基本的連接(concat)滴铅,接下來远荠,我們將討論附加。 附加就像連接的第一個例子失息,只是更加強(qiáng)大一些譬淳,因為數(shù)據(jù)幀會簡單地追加到行上。 我們通過一個例子來展示它的工作原理盹兢,同時也展示它可能出錯的地方:
df4 = df1.append(df2)
print(df4)
HPI Int_rate US_GDP_Thousands
2001 80 2 50
2002 85 3 55
2003 88 2 65
2004 85 2 55
2005 80 2 50
2006 85 3 55
2007 88 2 65
2008 85 2 55
這就是我們期望的附加邻梆。 在大多數(shù)情況下,你將要做這樣的事情绎秒,就像在數(shù)據(jù)庫中插入新行一樣浦妄。 我們并沒有真正有效地附加數(shù)據(jù)幀,它們更像是根據(jù)它們的起始數(shù)據(jù)來操作,但是如果你需要剂娄,你可以附加蠢涝。 當(dāng)我們附加索引相同的數(shù)據(jù)時會發(fā)生什么?
df4 = df1.append(df3)
print(df4)
HPI Int_rate Low_tier_HPI US_GDP_Thousands
2001 80 2 NaN 50
2002 85 3 NaN 55
2003 88 2 NaN 65
2004 85 2 NaN 55
2001 80 2 50 NaN
2002 85 3 52 NaN
2003 88 2 50 NaN
2004 85 2 53 NaN
好吧阅懦,這很不幸和二。 有人問為什么連接(concat )和附加都退出了。 這就是原因耳胎。 因為共有列包含相同的數(shù)據(jù)和相同的索引惯吕,所以組合這些數(shù)據(jù)幀要高效得多。 一個另外的例子是附加一個序列怕午。 鑒于append
的性質(zhì)废登,你可能會附加一個序列而不是一個數(shù)據(jù)幀。 至此我們還沒有談到序列郁惜。 序列基本上是單列的數(shù)據(jù)幀堡距。 序列確實有索引,但是兆蕉,如果你把它轉(zhuǎn)換成一個列表吏颖,它將僅僅是這些值。 每當(dāng)我們調(diào)用df ['column']
時恨樟,返回值就是一個序列半醉。
s = pd.Series([80,2,50], index=['HPI','Int_rate','US_GDP_Thousands'])
df4 = df1.append(s, ignore_index=True)
print(df4)
HPI Int_rate US_GDP_Thousands
0 80 2 50
1 85 3 55
2 88 2 65
3 85 2 55
4 80 2 50
在附加序列時,我們必須忽略索引劝术,因為這是規(guī)則缩多,除非序列擁有名稱。
在這里养晋,我們已經(jīng)介紹了 Pandas 中的連接(concat)和附加數(shù)據(jù)幀衬吆。 接下來,我們將討論如何連接(join)和合并數(shù)據(jù)幀绳泉。
六逊抡、連接(join)和合并數(shù)據(jù)幀
歡迎閱讀 Python 和 Pandas 數(shù)據(jù)分析系列教程的第六部分匹摇。 在這一部分種飒赃,我們將討論連接(join)和合并數(shù)據(jù)幀,作為組合數(shù)據(jù)框的另一種方法熏矿。 在前面的教程中四苇,我們介紹了連接(concat)和附加孝凌。
首先,我們將從以前的一些示例數(shù)據(jù)幀開始月腋,帶有一點(diǎn)更改:
import pandas as pd
df1 = pd.DataFrame({'HPI':[80,85,88,85],
'Int_rate':[2, 3, 2, 2],
'US_GDP_Thousands':[50, 55, 65, 55]},
index = [2001, 2002, 2003, 2004])
df2 = pd.DataFrame({'HPI':[80,85,88,85],
'Int_rate':[2, 3, 2, 2],
'US_GDP_Thousands':[50, 55, 65, 55]},
index = [2005, 2006, 2007, 2008])
df3 = pd.DataFrame({'HPI':[80,85,88,85],
'Unemployment':[7, 8, 9, 6],
'Low_tier_HPI':[50, 52, 50, 53]},
index = [2001, 2002, 2003, 2004])
唯一的變化是df3
蟀架,我們把Int_rate
變成了unemployment
瓣赂。 首先,我們來討論合并片拍。
print(pd.merge(df1,df3, on='HPI'))
HPI Int_rate US_GDP_Thousands Low_tier_HPI Unemployment
0 80 2 50 50 7
1 85 3 55 52 8
2 85 3 55 53 6
3 85 2 55 52 8
4 85 2 55 53 6
5 88 2 65 50 9
所以煌集,在這里,我們看到了一個共有列(HPI
)捌省。 你可以共有多個列苫纤,這里有一個例子:
print(pd.merge(df1,df2, on=['HPI','Int_rate']))
HPI Int_rate US_GDP_Thousands_x US_GDP_Thousands_y
0 80 2 50 50
1 85 3 55 55
2 88 2 65 65
3 85 2 55 55
注意這里有US_GDP_Thousands
的兩個版本。這是因為我們沒有共享這些列所禀,所以都保留下來,使用另外一個字母來區(qū)分放钦。記得之前我說過色徘,Pandas 是一個很好的模塊,與類似 MySQL 的數(shù)據(jù)庫結(jié)合操禀。這就是原因褂策。
通常,對于數(shù)據(jù)庫颓屑,你希望使其盡可能輕量化斤寂,以便在其上運(yùn)行的查詢執(zhí)行得盡可能快。
假設(shè)你運(yùn)營像pythonprogramming.net
這樣的網(wǎng)站揪惦,在那里你有用戶遍搞,所以你必須跟蹤用戶名和加密的密碼散列,所以這肯定是兩列器腋。也許那么你有登錄名溪猿,用戶名,密碼纫塌,電子郵件和注冊日期诊县。所以這已經(jīng)是基本數(shù)據(jù)點(diǎn)的五列。如果你有一個論壇措左,那么也許你有一些東西依痊,像用戶設(shè)置,帖子怎披。那么也許你希望有像管理員胸嘁,主持人,普通用戶的設(shè)置凉逛。
列表可以繼續(xù)缴渊。如果你在字面上只有一個巨大的表,這可以工作鱼炒,但把表分開也可能更好衔沼,因為許多操作將更快蝌借,更高效。 合并之后指蚁,你可能會設(shè)置新的索引菩佑。像這樣的東西:
df4 = pd.merge(df1,df3, on='HPI')
df4.set_index('HPI', inplace=True)
print(df4)
Int_rate US_GDP_Thousands Low_tier_HPI Unemployment
HPI
80 2 50 50 7
85 3 55 52 8
85 3 55 53 6
85 2 55 52 8
85 2 55 53 6
88 2 65 50 9
現(xiàn)在,如果HPI
已經(jīng)是索引了呢凝化? 或者稍坯,在我們的情況下,我們可能會按照日期連接搓劫,但日期可能是索引瞧哟。 在這種情況下,我們可能會使用連接(join)枪向。
df1.set_index('HPI', inplace=True)
df3.set_index('HPI', inplace=True)
joined = df1.join(df3)
print(joined)
Int_rate US_GDP_Thousands Low_tier_HPI Unemployment
HPI
80 2 50 50 7
85 3 55 52 8
85 3 55 53 6
85 2 55 52 8
85 2 55 53 6
88 2 65 50 9
現(xiàn)在勤揩,我們考慮連接(join)和合并略有不同的索引。 讓我們重新定義df1
和df3
數(shù)據(jù)幀秘蛔,將它們變成:
df1 = pd.DataFrame({
'Int_rate':[2, 3, 2, 2],
'US_GDP_Thousands':[50, 55, 65, 55],
'Year':[2001, 2002, 2003, 2004]
})
df3 = pd.DataFrame({
'Unemployment':[7, 8, 9, 6],
'Low_tier_HPI':[50, 52, 50, 53],
'Year':[2001, 2003, 2004, 2005]})
這里陨亡,我們現(xiàn)在有相似的年份列,但日期不同深员。 df3
有 2005 年负蠕,但沒有 2002 年,df1
相反倦畅。 現(xiàn)在遮糖,當(dāng)我們合并時會發(fā)生什么?
merged = pd.merge(df1,df3, on='Year')
print(merged)
Int_rate US_GDP_Thousands Year Low_tier_HPI Unemployment
0 2 50 2001 50 7
1 2 65 2003 52 8
2 2 55 2004 50 9
現(xiàn)在叠赐,更實用一些:
merged = pd.merge(df1,df3, on='Year')
merged.set_index('Year', inplace=True)
print(merged)
Int_rate US_GDP_Thousands Low_tier_HPI Unemployment
Year
2001 2 50 50 7
2003 2 65 52 8
2004 2 55 50 9
注意 2005 年和 2002 年完全失蹤了止吁。 合并只會合并現(xiàn)有/共有的數(shù)據(jù)。 我們能對其做些什么呢燎悍? 事實證明敬惦,合并時有一個參數(shù)how
。 此參數(shù)表明合并選擇谈山,它來自數(shù)據(jù)庫的合并俄删。 你有以下選擇:左、右奏路、外部畴椰、內(nèi)部。
- 左 - SQL 左外連接 - 僅使用左側(cè)數(shù)據(jù)幀中的鍵
- 右 - SQL 右外連接 - 僅使用右側(cè)數(shù)據(jù)幀中的鍵
- 外部 - 全外聯(lián)接 - 使用鍵的并集
- 內(nèi)部 - 使用鍵的交集
merged = pd.merge(df1,df3, on='Year', how='left')
merged.set_index('Year', inplace=True)
print(merged)
Int_rate US_GDP_Thousands Low_tier_HPI Unemployment
Year
2001 2 50 50 7
2002 3 55 NaN NaN
2003 2 65 52 8
2004 2 55 50 9
左側(cè)合并實際上在左邊的數(shù)據(jù)幀上鸽粉。 我們有df1
斜脂,df3
,左邊的是第一個触机,df1
帚戳。 所以玷或,我們最終得到了一個與左側(cè)數(shù)據(jù)幀(df1
)相同的索引。
merged = pd.merge(df1,df3, on='Year', how='right')
merged.set_index('Year', inplace=True)
print(merged)
Int_rate US_GDP_Thousands Low_tier_HPI Unemployment
Year
2001 2 50 50 7
2003 2 65 52 8
2004 2 55 50 9
2005 NaN NaN 53 6
我們選擇了右側(cè)片任,所以這次索引來源于右側(cè)(df3
)偏友。
merged = pd.merge(df1,df3, on='Year', how='outer')
merged.set_index('Year', inplace=True)
print(merged)
Int_rate US_GDP_Thousands Low_tier_HPI Unemployment
Year
2001 2 50 50 7
2002 3 55 NaN NaN
2003 2 65 52 8
2004 2 55 50 9
2005 NaN NaN 53 6
這次,我們選擇了外部对供,它是鍵的并集位他。也就是會展示所有索引。
merged = pd.merge(df1,df3, on='Year', how='inner')
merged.set_index('Year', inplace=True)
print(merged)
Int_rate US_GDP_Thousands Low_tier_HPI Unemployment
Year
2001 2 50 50 7
2003 2 65 52 8
2004 2 55 50 9
最后产场,“內(nèi)部”是鍵的交集鹅髓,基本上就是所有集合之間共有的東西。 這些都有其自己的邏輯京景,但是窿冯,正如你所看到的,默認(rèn)選項是“內(nèi)部”醋粟。
現(xiàn)在我們可以檢查連接(join)靡菇,這會按照索引連接重归,所以我們可以做這樣的事情:
df1.set_index('Year', inplace=True)
df3.set_index('Year', inplace=True)
joined = df1.join(df3, how="outer")
print(joined)
Int_rate US_GDP_Thousands Low_tier_HPI Unemployment
Year
2001 2 50 50 7
2002 3 55 NaN NaN
2003 2 65 52 8
2004 2 55 50 9
2005 NaN NaN 53 6
好吧米愿,我想我們已經(jīng)足以涵蓋了數(shù)據(jù)幀的組合。 讓我們回到我們的房地產(chǎn)投資鼻吮,使用我們的新知識育苟,并建立自己的史詩數(shù)據(jù)集。
七椎木、Pickle
歡迎閱讀 Python 和 Pandas 數(shù)據(jù)分析系列教程第七部分违柏。 在最近的幾個教程中,我們學(xué)習(xí)了如何組合數(shù)據(jù)集香椎。 在本教程中漱竖,我們將恢復(fù)我們是房地產(chǎn)巨頭的假設(shè)。 我們希望通過擁有多元化的財富來保護(hù)我們的財富畜伐,其中一個組成部分就是房地產(chǎn)馍惹。 在第 4部分 中,我們建立了以下代碼:
import Quandl
import pandas as pd
# Not necessary, I just do this so I do not show my API key.
api_key = open('quandlapikey.txt','r').read()
fiddy_states = pd.read_html('https://simple.wikipedia.org/wiki/List_of_U.S._states')
for abbv in fiddy_states[0][0][1:]:
#print(abbv)
print("FMAC/HPI_"+str(abbv))
這個代碼用來獲得 50 個州玛界,遍歷他們万矾,并產(chǎn)生適當(dāng)?shù)?Quandl 查詢,來按州返回房價指數(shù)慎框。 由于我們將在這里生成 50 個數(shù)據(jù)幀良狈,我們寧愿把它們?nèi)亢喜⒊梢粋€。 為此笨枯,我們可以使用前面教程中學(xué)到的.join
薪丁。 在這種情況下遇西,我們將使用.join
,因為 Quandl 模塊將數(shù)據(jù)返回給我們窥突,實際索引為Date
努溃。 通常情況下,你可能不會得到這個阻问,它只是索引為常規(guī)數(shù)字的數(shù)據(jù)幀梧税。 在這種情況下,你可以使用連接称近,on ='Date'
第队。
現(xiàn)在,為了運(yùn)行并收集所有的數(shù)據(jù)刨秆,我們可以做以下的改變:
import Quandl
import pandas as pd
# Not necessary, I just do this so I do not show my API key.
api_key = open('quandlapikey.txt','r').read()
fiddy_states = pd.read_html('https://simple.wikipedia.org/wiki/List_of_U.S._states')
main_df = pd.DataFrame()
for abbv in fiddy_states[0][0][1:]:
query = "FMAC/HPI_"+str(abbv)
df = Quandl.get(query, authtoken=api_key)
if main_df.empty:
main_df = df
else:
main_df = main_df.join(df)
注意:Quandl 已經(jīng)改變了數(shù)據(jù)集的返回值凳谦,如果返回值只有一列(或者我認(rèn)為是這樣),那么該列的標(biāo)題就是value
衡未。那么尸执,這很麻煩,但我們可以解決它缓醋。在for
循環(huán)中如失,將數(shù)據(jù)幀的列重命名為我們的縮寫。如果沒有做這個改變送粱,你可能會看到:ValueError: columns overlap but no suffix specified: Index([u'Value'], dtype='object')
褪贵。
太好了,但是每一次你想運(yùn)行它時抗俄,你會發(fā)現(xiàn)這個過程可能需要 30 秒到幾分鐘脆丁。這很煩人。現(xiàn)在动雹,你的短期目標(biāo)是實現(xiàn)它槽卫,但接下來呢?我們將繼續(xù)在此基礎(chǔ)上進(jìn)行研究胰蝠,每次我們進(jìn)行測試或者其他東西時歼培,我們都必須忍受這個無意義的東西!因此姊氓,我們要保存這些數(shù)據(jù)∝で樱現(xiàn)在,這是一個數(shù)據(jù)分析和 Pandas 教程翔横。有了 Pandas读跷,我們可以簡單地將數(shù)據(jù)輸出到 CSV,或者我們希望的任何數(shù)據(jù)類型禾唁,包括我們要談?wù)摰膬?nèi)容效览。但是无切,你可能并不總是可以將數(shù)據(jù)輸出到簡單文件。在任何情況下丐枉,我們都希望將這些數(shù)據(jù)保存到一個文件中哆键,所以我們只需要執(zhí)行一次這個操作,然后我們就可以在它頂上建立瘦锹。
舉個例子來說籍嘹,就是機(jī)器學(xué)習(xí)。你通常會訓(xùn)練一個分類器弯院,然后你可以立即開始辱士,然后快速使用該分類器進(jìn)行分類。問題是听绳,分類器不能保存到.txt
或.csv
文件颂碘。這是一個對象。幸運(yùn)的是椅挣,以編程的方式头岔,有各種各樣的東西,用于將二進(jìn)制數(shù)據(jù)保存到可以稍后訪問的文件鼠证。在 Python 中峡竣,這被稱為 Pickle。你可能知道它是序列化的名惩,或者甚至別的東西澎胡。 Python 有一個名為 Pickle 的模塊孕荠,它將把你的對象轉(zhuǎn)換成一個字節(jié)流娩鹉,或者反過來轉(zhuǎn)換它。這讓我們做的是保存任何 Python 對象稚伍。那機(jī)器學(xué)習(xí)分類器呢弯予?可以。字典个曙?可以锈嫩。數(shù)據(jù)幀?可以垦搬!現(xiàn)在呼寸,Pandas 在 IO 模塊中已經(jīng)有了 Pickle,但是你真的應(yīng)該知道如何使用和不使用 Pandas 來實現(xiàn)它猴贰,所以讓我們這樣做吧对雪!
首先,我們來談?wù)劤R?guī)的 Pickle米绕。你可以用你想要的任何 Python 對象來這樣做瑟捣,它不需要是一個數(shù)據(jù)幀馋艺,但我們會用我們的數(shù)據(jù)幀來實現(xiàn)。
首先迈套,在腳本的頂部導(dǎo)入pickle
:
import pickle
下面:
pickle_out = open('fiddy_states.pickle','wb')
pickle.dump(main_df, pickle_out)
pickle_out.close()
首先我們打開一個.pickle
文件捐祠,打算寫一些字節(jié)。 然后桑李,我們執(zhí)行pickle.dump
來轉(zhuǎn)儲我們想要保存的數(shù)據(jù)踱蛀,之后是轉(zhuǎn)儲它的地方(我們剛才打開的文件)鳖链。 最后莲组,我們關(guān)閉任何文件附鸽。 完成了蔗喂,我們保存了pickle
绝骚。
不過蒸播,我希望現(xiàn)在組織這些代碼茂腥。 我們不希望每次都運(yùn)行這個代碼井联,但是我們?nèi)匀恍枰獣r常引用狀態(tài)列表圈浇。 我們來清理一下:
import Quandl
import pandas as pd
import pickle
# Not necessary, I just do this so I do not show my API key.
api_key = open('quandlapikey.txt','r').read()
def state_list():
fiddy_states = pd.read_html('https://simple.wikipedia.org/wiki/List_of_U.S._states')
return fiddy_states[0][0][1:]
def grab_initial_state_data():
states = state_list()
main_df = pd.DataFrame()
for abbv in states:
query = "FMAC/HPI_"+str(abbv)
df = Quandl.get(query, authtoken=api_key)
print(query)
if main_df.empty:
main_df = df
else:
main_df = main_df.join(df)
pickle_out = open('fiddy_states.pickle','wb')
pickle.dump(main_df, pickle_out)
pickle_out.close()
grab_initial_state_data()
現(xiàn)在寥掐,我們可以在任何需要狀態(tài)列表的時候,引用state_list
磷蜀,然后我們只需要為HPI
基線調(diào)用grab_initial_state_data
召耘,真的比較快,并且我們已經(jīng)將這些數(shù)據(jù)保存到了pickle
文件中褐隆。
現(xiàn)在污它,再次獲取這些數(shù)據(jù),我們只需要做:
pickle_in = open('fiddy_states.pickle','rb')
HPI_data = pickle.load(pickle_in)
print(HPI_data)
輸出比我想要粘貼的更多庶弃,但是你應(yīng)該得到一個約 462 行 x50 列的數(shù)據(jù)幀衫贬。 你有了它。 部分對象是它是一個數(shù)據(jù)幀歇攻,這是我們“保存”變量的方式固惯。 很酷! 你可以在 Python 的任何地方用pickle
模塊來這樣做缴守,但是 Pandas 也有自己的pickle
葬毫,所以我們可以展示:
HPI_data.to_pickle('pickle.pickle')
HPI_data2 = pd.read_pickle('pickle.pickle')
print(HPI_data2)
再次,輸出有點(diǎn)多屡穗,不能粘貼在這里贴捡,但你應(yīng)該得到同樣的東西。 如果你和我一樣村砂,你可能會想“如果所有的 Python 已經(jīng)有 Pickle 并且工作得很好烂斋,為什么 Pandas 有自己的 Pickle 選項?” 我真的不知道。 顯然源祈,Pandas 有時可以更快地處理海量數(shù)據(jù)煎源。
現(xiàn)在我們已經(jīng)得到了數(shù)據(jù)的pickle
,我們已經(jīng)準(zhǔn)備好在下一篇教程中繼續(xù)深入研究香缺。
八手销、百分比變化和相關(guān)表
歡迎閱讀 Python 和 Pandas 數(shù)據(jù)分析系列教程的第八部分。 在這一部分中图张,我們將對數(shù)據(jù)進(jìn)行一些初步的操作锋拖。 我們到目前為止的腳本是:
import Quandl
import pandas as pd
import pickle
# Not necessary, I just do this so I do not show my API key.
api_key = open('quandlapikey.txt','r').read()
def state_list():
fiddy_states = pd.read_html('https://simple.wikipedia.org/wiki/List_of_U.S._states')
return fiddy_states[0][0][1:]
def grab_initial_state_data():
states = state_list()
main_df = pd.DataFrame()
for abbv in states:
query = "FMAC/HPI_"+str(abbv)
df = Quandl.get(query, authtoken=api_key)
print(query)
if main_df.empty:
main_df = df
else:
main_df = main_df.join(df)
pickle_out = open('fiddy_states.pickle','wb')
pickle.dump(main_df, pickle_out)
pickle_out.close()
HPI_data = pd.read_pickle('fiddy_states.pickle')
現(xiàn)在我們可以像這樣修改列:
HPI_data['TX2'] = HPI_data['TX'] * 2
print(HPI_data[['TX','TX2']].head())
TX TX2
Date
1975-01-31 32.617930 65.235860
1975-02-28 33.039339 66.078677
1975-03-31 33.710029 67.420057
1975-04-30 34.606874 69.213747
1975-05-31 34.864578 69.729155
我們我們也可以不創(chuàng)建新的列,只是重新定義原來的TX
祸轮。 從我們的腳本中刪除整個TX2
的代碼兽埃,讓我們看看我們現(xiàn)在有什么。 在腳本的頂部:
import matplotlib.pyplot as plt
from matplotlib import style
style.use('fivethirtyeight')
之后:
HPI_data.plot()
plt.legend().remove()
plt.show()
輸出:
https://pythonprogramming.net/static/images/pandas/pandas-percent-change-tutorial-1.png
嗯适袜,有趣柄错,發(fā)生了什么事? 所有這些價格似乎在 2000 年完美匯合苦酱!這正是指數(shù)從 100.0% 開始的時候售貌。 我們可以得到它,但我根本不喜歡疫萤。 那么某種百分比變化呢颂跨? 事實證明,Pandas 在這里覆蓋了各種“滾動”統(tǒng)計量扯饶。 我們可以用一個基本的恒削,就像這樣:
def grab_initial_state_data():
states = state_list()
main_df = pd.DataFrame()
for abbv in states:
query = "FMAC/HPI_"+str(abbv)
df = Quandl.get(query, authtoken=api_key)
print(query)
df = df.pct_change()
print(df.head())
if main_df.empty:
main_df = df
else:
main_df = main_df.join(df)
pickle_out = open('fiddy_states2.pickle','wb')
pickle.dump(main_df, pickle_out)
pickle_out.close()
grab_initial_state_data()
主要是,你要注意:df = df.pct_change()
尾序,我們將重新運(yùn)行它钓丰,保存到fiddy_states2.pickle
。 值得注意的是蹲诀,我們也可以嘗試修改原來的 Pickle斑粱,而不是重新構(gòu)建弃揽。 畢竟脯爪,這就是 Pickle 的要點(diǎn)。 如果我沒有事后偏見矿微,我可能會同意你的看法痕慢。
HPI_data = pd.read_pickle('fiddy_states2.pickle')
HPI_data.plot()
plt.legend().remove()
plt.show()
輸出:
https://pythonprogramming.net/static/images/pandas/pandas-percent-change-graph-2.png
不幸的是,我不是那么想的涌矢。 我想要一個傳統(tǒng)的百分比變化圖掖举。 這是距離上次報告值的百分比變化。 我們可以增加它娜庇,做一些事情塔次,類似于過去 10 個值的滾動百分比方篮,但仍然不是我想要的。 我們來試試其他的東西:
def grab_initial_state_data():
states = state_list()
main_df = pd.DataFrame()
for abbv in states:
query = "FMAC/HPI_"+str(abbv)
df = Quandl.get(query, authtoken=api_key)
print(query)
df[abbv] = (df[abbv]-df[abbv][0]) / df[abbv][0] * 100.0
print(df.head())
if main_df.empty:
main_df = df
else:
main_df = main_df.join(df)
pickle_out = open('fiddy_states3.pickle','wb')
pickle.dump(main_df, pickle_out)
pickle_out.close()
grab_initial_state_data()
HPI_data = pd.read_pickle('fiddy_states3.pickle')
HPI_data.plot()
plt.legend().remove()
plt.show()
https://pythonprogramming.net/static/images/pandas/pandas-percent-change-graph-tutorial-3.png
好的励负,這就是我要找的藕溅! 這是每個州 HPI 自身的百分比變化。 出于各種原因继榆,第一個百分比變化仍然有用巾表。 我們可能會結(jié)合使用這個結(jié)果,或者取而代之略吨,但是現(xiàn)在集币,我們最開始堅持使用典型的百分比變化。
現(xiàn)在翠忠,我們可能想要引入其他數(shù)據(jù)集鞠苟,但是讓我們看看我們是否可以自己到達(dá)任何地方。 首先秽之,我們可以檢查某種“基準(zhǔn)”偶妖。 對于這個數(shù)據(jù),這個基準(zhǔn)將是美國的房價指數(shù)政溃。 我們可以收集:
def HPI_Benchmark():
df = Quandl.get("FMAC/HPI_USA", authtoken=api_key)
df["United States"] = (df["United States"]-df["United States"][0]) / df["United States"][0] * 100.0
return df
之后:
fig = plt.figure()
ax1 = plt.subplot2grid((1,1), (0,0))
HPI_data = pd.read_pickle('fiddy_states3.pickle')
benchmark = HPI_Benchmark()
HPI_data.plot(ax=ax1)
benchmark.plot(color='k',ax=ax1, linewidth=10)
plt.legend().remove()
plt.show()
輸出:
https://pythonprogramming.net/static/images/pandas/pandas-pct-change-tutorial-4.png
從這個數(shù)據(jù)來看趾访,似乎是所有的市場都是相對密切地服從彼此和整體房價指數(shù)。這里確實存在一些平均偏差董虱,但基本上每個市場似乎都遵循了非常相似的趨勢扼鞋。其中最大的偏差是從 200% 的增長到 800% 的增長,顯然我們有很大的偏差愤诱,但是在過去的 30 年里云头,均值從 400% 增長到 500%。
我們?nèi)绾谓咏袌瞿匾耄恐罄;保覀兛梢钥紤]人口統(tǒng)計和利率來預(yù)測未來,但不是每個人都對投機(jī)游戲感興趣科吭。有些人想要更安全昏滴,更安全的投資。在這里看來对人,像房地產(chǎn)市場從來沒有真正在國家層面失敗谣殊。如果我們買房子,顯然我們的計劃可能會失敗牺弄,之后我們發(fā)現(xiàn)了巨大白蟻危害姻几,并可能在任何時候倒塌。
保持宏觀,我很清楚蛇捌,我們可以在這里進(jìn)行一個非常明顯抚恒,安全的交易。我們可以使用 Pandas 很容易地收集相關(guān)性和協(xié)方差信息络拌。相關(guān)性和協(xié)方差是兩個非常相似的話題柑爸,經(jīng)常被混淆。相關(guān)不是因果關(guān)系盒音,相關(guān)性幾乎總是包含在協(xié)方差計算中用于歸一化表鳍。相關(guān)性衡量了兩個資產(chǎn)相對于彼此移動的程度。協(xié)方差是衡量兩個資產(chǎn)如何一起變化的指標(biāo)祥诽。注意相關(guān)性是對“程度”的一種度量譬圣。協(xié)方差不是。如果我自己的理解不正確雄坪,這是重要的區(qū)別厘熟。
我們來創(chuàng)建一個關(guān)聯(lián)表。這將為我們做的事情维哈,是歷史回顧绳姨,衡量每個州與其他州的移動之間的相關(guān)性。那么阔挠,當(dāng)兩個通常高度相關(guān)的州開始出現(xiàn)不一致的時候飘庄,我們可以考慮出售正在上升的州的房地產(chǎn),并購買正在下降的州的房地產(chǎn)作為一種市場中性策略购撼,其中我們僅僅從差距中獲益跪削,而不是做一些預(yù)測未來的嘗試。相互接壤的州更有可能比遠(yuǎn)離的州更相似迂求,但是我們會看到數(shù)字說了些什么碾盐。
HPI_data = pd.read_pickle('fiddy_states3.pickle')
HPI_State_Correlation = HPI_data.corr()
print(HPI_State_Correlation)
輸出是 50 行 x50 列,這里是一些輸出揩局。
AL AK AZ AR CA CO CT \
AL 1.000000 0.944603 0.927361 0.994896 0.935970 0.979352 0.953724
AK 0.944603 1.000000 0.893904 0.965830 0.900621 0.949834 0.896395
AZ 0.927361 0.893904 1.000000 0.923786 0.973546 0.911422 0.917500
AR 0.994896 0.965830 0.923786 1.000000 0.935364 0.985934 0.948341
CA 0.935970 0.900621 0.973546 0.935364 1.000000 0.924982 0.956495
CO 0.979352 0.949834 0.911422 0.985934 0.924982 1.000000 0.917129
CT 0.953724 0.896395 0.917500 0.948341 0.956495 0.917129 1.000000
DE 0.980566 0.939196 0.942273 0.975830 0.970232 0.949517 0.981177
FL 0.918544 0.887891 0.994007 0.915989 0.987200 0.905126 0.926364
GA 0.973562 0.880261 0.939715 0.960708 0.943928 0.959500 0.948500
HI 0.946054 0.930520 0.902554 0.947022 0.937704 0.903461 0.938974
ID 0.982868 0.944004 0.959193 0.977372 0.944342 0.960975 0.923099
IL 0.984782 0.905512 0.947396 0.973761 0.963858 0.968552 0.955033
IN 0.981189 0.889734 0.881542 0.973259 0.901154 0.971416 0.919696
IA 0.985516 0.943740 0.894524 0.987919 0.914199 0.991455 0.913788
KS 0.990774 0.957236 0.910948 0.995230 0.926872 0.994866 0.936523
KY 0.994311 0.938125 0.900888 0.992903 0.923429 0.987097 0.941114
LA 0.967232 0.990506 0.909534 0.982454 0.911742 0.972703 0.907456
ME 0.972693 0.935850 0.923797 0.972573 0.965251 0.951917 0.989180
MD 0.964917 0.943384 0.960836 0.964943 0.983677 0.940805 0.969170
MA 0.966242 0.919842 0.921782 0.966962 0.962672 0.959294 0.986178
MI 0.891205 0.745697 0.848602 0.873314 0.861772 0.900040 0.843032
MN 0.971967 0.926352 0.952359 0.972338 0.970661 0.983120 0.945521
MS 0.996089 0.962494 0.927354 0.997443 0.932752 0.985298 0.945831
MO 0.992706 0.933201 0.938680 0.989672 0.955317 0.985194 0.961364
MT 0.977030 0.976840 0.916000 0.983822 0.923950 0.971516 0.917663
NE 0.988030 0.941229 0.896688 0.990868 0.912736 0.992179 0.920409
NV 0.858538 0.785404 0.965617 0.846968 0.948143 0.837757 0.866554
NH 0.953366 0.907236 0.932992 0.952882 0.969574 0.941555 0.990066
NJ 0.968837 0.934392 0.943698 0.967477 0.975258 0.944460 0.989845
NM 0.992118 0.967777 0.934744 0.993195 0.934720 0.968001 0.946073
NY 0.973984 0.940310 0.921126 0.973972 0.959543 0.949474 0.989576
NC 0.998383 0.934841 0.915403 0.991863 0.928632 0.977069 0.956074
ND 0.936510 0.973971 0.840705 0.957838 0.867096 0.942225 0.882938
OH 0.966598 0.855223 0.883396 0.954128 0.901842 0.957527 0.911510
OK 0.944903 0.984550 0.881332 0.967316 0.882199 0.960694 0.879854
OR 0.981180 0.948190 0.949089 0.978144 0.944542 0.971110 0.916942
PA 0.985357 0.946184 0.915914 0.983651 0.950621 0.956316 0.975324
RI 0.950261 0.897159 0.943350 0.945984 0.984298 0.926362 0.988351
SC 0.998603 0.945949 0.929591 0.994117 0.942524 0.980911 0.959591
SD 0.983878 0.966573 0.889405 0.990832 0.911188 0.984463 0.924295
TN 0.998285 0.946858 0.919056 0.995949 0.931616 0.983089 0.953009
TX 0.963876 0.983235 0.892276 0.981413 0.902571 0.970795 0.919415
UT 0.983987 0.951873 0.926676 0.982867 0.909573 0.974909 0.900908
VT 0.975210 0.952370 0.909242 0.977904 0.949225 0.951388 0.973716
VA 0.972236 0.956925 0.950839 0.975683 0.977028 0.954801 0.970366
WA 0.988253 0.948562 0.950262 0.982877 0.956434 0.968816 0.941987
WV 0.984364 0.964846 0.907797 0.990264 0.924300 0.979467 0.925198
WI 0.990190 0.930548 0.927619 0.985818 0.943768 0.987609 0.936340
WY 0.944600 0.983109 0.892255 0.960336 0.897551 0.950113 0.880035
所以現(xiàn)在我們可以看到毫玖,每兩個州之間的 HPI 移動的相關(guān)性。 非常有趣凌盯,顯而易見付枫,所有這些都非常高。 相關(guān)性的范圍從 -1 到 1十气。1 是個完美的正相關(guān)励背,-1 是個完美的負(fù)相關(guān)。 協(xié)方差沒有界限砸西。 想知道更多的統(tǒng)計量嘛? Pandas 有一個非常漂亮的描述方法:
print(HPI_State_Correlation.describe())
AL AK AZ AR CA CO \
count 50.000000 50.000000 50.000000 50.000000 50.000000 50.000000
mean 0.969114 0.932978 0.922772 0.969600 0.938254 0.958432
std 0.028069 0.046225 0.031469 0.029532 0.031033 0.030502
min 0.858538 0.745697 0.840705 0.846968 0.861772 0.837757
25% 0.956262 0.921470 0.903865 0.961767 0.916507 0.949485
50% 0.976120 0.943562 0.922784 0.976601 0.940114 0.964488
75% 0.987401 0.957159 0.943081 0.989234 0.961890 0.980550
max 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
CT DE FL GA ... SD \
count 50.000000 50.000000 50.000000 50.000000 ... 50.000000
mean 0.938752 0.963892 0.920650 0.945985 ... 0.959275
std 0.035402 0.028814 0.035204 0.030631 ... 0.039076
min 0.843032 0.846668 0.833816 0.849962 ... 0.794846
25% 0.917541 0.950417 0.899680 0.934875 ... 0.952632
50% 0.941550 0.970461 0.918904 0.949980 ... 0.972660
75% 0.960920 0.980587 0.944646 0.964282 ... 0.982252
max 1.000000 1.000000 1.000000 1.000000 ... 1.000000
TN TX UT VT VA WA \
count 50.000000 50.000000 50.000000 50.000000 50.000000 50.000000
mean 0.968373 0.944410 0.953990 0.959094 0.963491 0.966678
std 0.029649 0.039712 0.033818 0.035041 0.029047 0.025752
min 0.845672 0.791177 0.841324 0.817081 0.828781 0.862245
25% 0.955844 0.931489 0.936264 0.952458 0.955986 0.954070
50% 0.976294 0.953301 0.956764 0.968237 0.970380 0.974049
75% 0.987843 0.967444 0.979966 0.976644 0.976169 0.983541
max 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
WV WI WY
count 50.000000 50.000000 50.000000
mean 0.961813 0.965621 0.932232
std 0.035339 0.026125 0.048678
min 0.820529 0.874777 0.741663
25% 0.957074 0.950046 0.915386
50% 0.974099 0.973141 0.943979
75% 0.984067 0.986954 0.961900
max 1.000000 1.000000 1.000000
[8 rows x 50 columns]
這告訴我們,對于每個州芹枷,最低的相關(guān)性是什么衅疙,平均相關(guān)性是什么,標(biāo)準(zhǔn)差是什么鸳慈,前 25%饱溢,中間值(中位數(shù)/ 50%)等等。顯然他們最大都為 1.0走芋,因為他們是完全相關(guān)的绩郎。然而,最重要的是翁逞,我們在這里看到的所有這些州(50 列中的一些被跳過肋杖,我們從 GA 到 SD)與其他所有州的相關(guān)度平均上高于 90%。懷俄明州與一個州的相關(guān)度低至 74%挖函,在看了我們的表后状植,它就是密歇根州。正因為如此怨喘,如果密歇根州上升津畸,我們可能不想在懷俄明州投資,或者因為懷俄明州正在陷入困境而必怜,出售我們在密歇根州的房子肉拓。
我們不僅可以從整體指數(shù)中看到任何偏差,還可以從個別市場中尋找偏差梳庆。正如你所看到的帝簇,我們有每個州的標(biāo)準(zhǔn)差數(shù)字。當(dāng)市場低于標(biāo)準(zhǔn)偏差時靠益,我們可以嘗試投資于房地產(chǎn)丧肴,或者當(dāng)市場高于標(biāo)準(zhǔn)偏差時賣出。在我們到達(dá)那里之前胧后,讓我們在下一個教程中討論平滑數(shù)據(jù)以及重采樣的概念芋浮。
九、重采樣
歡迎閱讀另一個 Python 和 Pandas 數(shù)據(jù)分析教程壳快。在本教程中纸巷,我們將討論通過消除噪音來平滑數(shù)據(jù)。有兩種主要的方法來實現(xiàn)眶痰。所使用的最流行的方法是稱為重采樣瘤旨,但可能具有許多其他名稱。這是我們有一些數(shù)據(jù)竖伯,以一定的比例抽樣存哲。對我們來說因宇,我們的房屋價格指數(shù)是按一個月抽樣的,但是我們可以每周祟偷,每一天察滑,每一分鐘或更多時間對 HPI 進(jìn)行抽樣,但是我們也可以每年修肠,每隔 10 年重新抽樣贺辰。
例如,重新抽樣經(jīng)常出現(xiàn)的另一個環(huán)境就是股價嵌施。股票價格是二手?jǐn)?shù)據(jù)饲化。所發(fā)生的事情是,對于免費(fèi)數(shù)據(jù)吗伤,股票價格通常最低被重新采樣為分鐘數(shù)據(jù)吃靠。但是,你可以購買實時數(shù)據(jù)牲芋。從長遠(yuǎn)來看撩笆,數(shù)據(jù)通常會每天采樣,甚至每 3-5 天采樣一次缸浦。這通常是為了使傳輸數(shù)據(jù)的大小保持較小夕冲。例如,在一年的過程中裂逐,二手?jǐn)?shù)據(jù)通常是幾個 GB歹鱼,并且一次全部傳輸是不合理的,人們將等待幾分鐘或幾小時來加載頁面卜高。
使用我們目前每個月抽樣一次的數(shù)據(jù)弥姻,我們怎樣才能每六個月或兩年抽樣一次呢?試著想想如何親自編寫一個能執(zhí)行這個任務(wù)的函數(shù)掺涛,這是一個相當(dāng)具有挑戰(zhàn)性的函數(shù)庭敦,但是它可以完成。也就是說薪缆,這是一個計算效率相當(dāng)?shù)偷墓ぷ餮砹?Pandas 會幫助我們,并且速度非臣鹈保快疼电。讓我們來看看。我們現(xiàn)在的起始腳本:
import Quandl
import pandas as pd
import pickle
import matplotlib.pyplot as plt
from matplotlib import style
style.use('fivethirtyeight')
# Not necessary, I just do this so I do not show my API key.
api_key = open('quandlapikey.txt','r').read()
def state_list():
fiddy_states = pd.read_html('https://simple.wikipedia.org/wiki/List_of_U.S._states')
return fiddy_states[0][0][1:]
def grab_initial_state_data():
states = state_list()
main_df = pd.DataFrame()
for abbv in states:
query = "FMAC/HPI_"+str(abbv)
df = Quandl.get(query, authtoken=api_key)
print(query)
df[abbv] = (df[abbv]-df[abbv][0]) / df[abbv][0] * 100.0
print(df.head())
if main_df.empty:
main_df = df
else:
main_df = main_df.join(df)
pickle_out = open('fiddy_states3.pickle','wb')
pickle.dump(main_df, pickle_out)
pickle_out.close()
def HPI_Benchmark():
df = Quandl.get("FMAC/HPI_USA", authtoken=api_key)
df["United States"] = (df["United States"]-df["United States"][0]) / df["United States"][0] * 100.0
return df
fig = plt.figure()
ax1 = plt.subplot2grid((1,1), (0,0))
HPI_data = pd.read_pickle('fiddy_states3.pickle')
HPI_State_Correlation = HPI_data.corr()
首先减拭,讓我們更簡單一點(diǎn)蔽豺,首先參考德克薩斯州的信息就斤,然后重新抽樣:
TX1yr = HPI_data['TX'].resample('A')
print(TX1yr.head())
Date
1975-12-31 4.559105
1976-12-31 11.954152
1977-12-31 23.518179
1978-12-31 41.978042
1979-12-31 64.700665
Freq: A-DEC, Name: TX, dtype: float64
我們以A
重新采樣嘱蛋,這會每年重新采樣(年終)灶搜。 你可以在這里找到所有的resample
選項:http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases
善玫,但這里是我寫這篇教程時的最新版本:
Resample rule:
xL for milliseconds
xMin for minutes
xD for Days
Alias Description
B business day frequency
C custom business day frequency (experimental)
D calendar day frequency
W weekly frequency
M month end frequency
BM business month end frequency
CBM custom business month end frequency
MS month start frequency
BMS business month start frequency
CBMS custom business month start frequency
Q quarter end frequency
BQ business quarter endfrequency
QS quarter start frequency
BQS business quarter start frequency
A year end frequency
BA business year end frequency
AS year start frequency
BAS business year start frequency
BH business hour frequency
H hourly frequency
T minutely frequency
S secondly frequency
L milliseonds
U microseconds
N nanoseconds
How:
mean, sum, ohlc
現(xiàn)在我們可以比較兩個數(shù)據(jù)集:
HPI_data['TX'].plot(ax=ax1)
TX1yr.plot(color='k',ax=ax1)
plt.legend().remove()
plt.show()
https://pythonprogramming.net/static/images/pandas/pandas-resampling-tutorial.png
你可以看到,從月度數(shù)據(jù)變?yōu)槟甓葦?shù)據(jù)并沒有真正向我們隱藏趨勢線本身的任何信息濒析,但是至少在德克薩斯州正什,有一件有趣的事情需要注意啥纸,你覺得月度數(shù)據(jù)中的那些扭曲看起來有些模式化号杏?我反正是。你可以將鼠標(biāo)懸停在所有峰值上斯棒,然后開始查看出現(xiàn)峰值的一年中的月份盾致。大部分峰值出現(xiàn)在 6 月左右,幾乎每個最低值都在 12 月左右荣暮。許多州都有這種模式庭惜,而且在美國的 HPI 中也是如此。也許我們會玩玩這些趨勢穗酥,并完成整個教程护赊!我們現(xiàn)在是專家!
好的不完全是砾跃,我想我們會繼續(xù)教程骏啰。所以通過重新采樣,我們可以選擇間隔抽高,以及我們希望“如何”重新采樣判耕。默認(rèn)是按照均值,但也有一個時期的總和翘骂。如果我們按年份重采樣壁熄,使用how=sum
,那么收益就是這一年所有 HPI 值的總和碳竟。最后是 OHLC草丧,這是高開低收。這將返回這個期間的起始值莹桅,最高值昌执,最低值和最后一個值。
我認(rèn)為我們最好堅持使用月度數(shù)據(jù)统翩,但重新采樣絕對值得在任何 Pandas 教程中涵蓋∠裳粒現(xiàn)在,你可能想知道厂汗,為什么我們?yōu)橹夭蓸觿?chuàng)建了一個新的數(shù)據(jù)幀委粉,而不是將其添加到現(xiàn)有的數(shù)據(jù)幀中。原因是它會創(chuàng)建大量的NaN
數(shù)據(jù)娶桦。有時候贾节,即使只是原始的重采樣也會包含NaN
數(shù)據(jù)汁汗,特別是如果你的數(shù)據(jù)不按照統(tǒng)一的時間間隔更新的話。處理丟失的數(shù)據(jù)是一個主要的話題栗涂,但是我們將在下一個教程中試圖廣泛地介紹它知牌,包括處理丟失數(shù)據(jù)的思路,以及如何通過程序處理你的選擇斤程。
十角寸、處理缺失數(shù)據(jù)
歡迎閱讀 Python 和 Pandas 數(shù)據(jù)分析教程的第 10 部分。在這一部分中忿墅,我們將討論缺失或不可用的數(shù)據(jù)扁藕。考慮到缺失數(shù)據(jù)的存在疚脐,我們有幾個選擇亿柑。
- 忽略它 - 只把它留在那里
- 刪除它 - 刪除所有的情況。完全從數(shù)據(jù)中刪除棍弄。這意味著放棄整行數(shù)據(jù)望薄。
- 向前或向后填充 - 這意味著只是采用之前或之后的值填充。
- 將其替換為靜態(tài)的東西 - 例如呼畸,用
-9999
替換所有的NaN
數(shù)據(jù)痕支。
由于各種原因,這些選項各有其優(yōu)點(diǎn)役耕。忽略它不需要我們更多的工作采转。你可能會出于法律原因選擇忽略丟失的數(shù)據(jù),或者保留數(shù)據(jù)的最大完整性瞬痘。缺失數(shù)據(jù)也可能是非常重要的數(shù)據(jù)故慈。例如,也許你的分析的一部分是調(diào)查服務(wù)器的信號丟失框全。在這種情況下察绷,缺失數(shù)據(jù)可能非常重要,需要保持在集合中津辩。
接下來拆撼,我們可以刪除它。在這里你有另外兩個選擇喘沿。如果行中包含任意數(shù)量的NaN
數(shù)據(jù)闸度,或者如果該行完全是NaN
數(shù)據(jù),則可以刪除這些行蚜印。通常莺禁,充滿NaN
數(shù)據(jù)的行來自你在數(shù)據(jù)集上執(zhí)行的計算,并且數(shù)據(jù)沒有真的丟失窄赋,只是你的公式不可用哟冬。在大多數(shù)情況下楼熄,你至少需要刪除所有完全是NaN
的行,并且在很多情況下浩峡,你只希望刪除任何具有NaN
數(shù)據(jù)的行可岂。我們該怎么做呢?我們將從以下腳本開始(請注意翰灾,現(xiàn)在通過在HPI_data
數(shù)據(jù)幀中添加一個新列缕粹,來完成重新采樣)。
import Quandl
import pandas as pd
import pickle
import matplotlib.pyplot as plt
from matplotlib import style
style.use('fivethirtyeight')
# Not necessary, I just do this so I do not show my API key.
api_key = open('quandlapikey.txt','r').read()
def state_list():
fiddy_states = pd.read_html('https://simple.wikipedia.org/wiki/List_of_U.S._states')
return fiddy_states[0][0][1:]
def grab_initial_state_data():
states = state_list()
main_df = pd.DataFrame()
for abbv in states:
query = "FMAC/HPI_"+str(abbv)
df = Quandl.get(query, authtoken=api_key)
print(query)
df[abbv] = (df[abbv]-df[abbv][0]) / df[abbv][0] * 100.0
print(df.head())
if main_df.empty:
main_df = df
else:
main_df = main_df.join(df)
pickle_out = open('fiddy_states3.pickle','wb')
pickle.dump(main_df, pickle_out)
pickle_out.close()
def HPI_Benchmark():
df = Quandl.get("FMAC/HPI_USA", authtoken=api_key)
df["United States"] = (df["United States"]-df["United States"][0]) / df["United States"][0] * 100.0
return df
##fig = plt.figure()
##ax1 = plt.subplot2grid((1,1), (0,0))
HPI_data = pd.read_pickle('fiddy_states3.pickle')
HPI_data['TX1yr'] = HPI_data['TX'].resample('A')
print(HPI_data[['TX','TX1yr']])
##HPI_data['TX'].plot(ax=ax1)
##HPI_data['TX1yr'].plot(color='k',ax=ax1)
##
##plt.legend().remove()
##plt.show()
我們現(xiàn)在注釋了繪圖的東西预侯,但是我們稍后會回顧它致开。
輸出:
TX TX1yr
Date
1975-01-31 0.000000 NaN
1975-02-28 1.291954 NaN
1975-03-31 3.348154 NaN
1975-04-30 6.097700 NaN
1975-05-31 6.887769 NaN
1975-06-30 5.566434 NaN
1975-07-31 4.710613 NaN
1975-08-31 4.612650 NaN
1975-09-30 4.831876 NaN
1975-10-31 5.192504 NaN
1975-11-30 5.832832 NaN
1975-12-31 6.336776 4.559105
1976-01-31 6.576975 NaN
1976-02-29 7.364782 NaN
1976-03-31 9.579950 NaN
1976-04-30 12.867197 NaN
1976-05-31 14.018165 NaN
1976-06-30 12.938501 NaN
1976-07-31 12.397848 NaN
1976-08-31 12.388581 NaN
1976-09-30 12.638779 NaN
1976-10-31 13.341849 NaN
1976-11-30 14.336404 NaN
1976-12-31 15.000798 11.954152
1977-01-31 15.555243 NaN
1977-02-28 16.921638 NaN
1977-03-31 20.118106 NaN
1977-04-30 25.186161 NaN
1977-05-31 26.260529 NaN
1977-06-30 23.430347 NaN
... ... ...
2011-01-31 280.574891 NaN
2011-02-28 281.202150 NaN
2011-03-31 282.772390 NaN
2011-04-30 284.374537 NaN
2011-05-31 286.518910 NaN
2011-06-30 288.665880 NaN
2011-07-31 288.232992 NaN
2011-08-31 285.507223 NaN
2011-09-30 283.408865 NaN
2011-10-31 282.348926 NaN
2011-11-30 282.026481 NaN
2011-12-31 282.384836 284.001507
2012-01-31 283.248573 NaN
2012-02-29 285.790368 NaN
2012-03-31 289.946517 NaN
2012-04-30 294.803887 NaN
2012-05-31 299.670256 NaN
2012-06-30 303.575682 NaN
2012-07-31 305.478743 NaN
2012-08-31 305.452329 NaN
2012-09-30 305.446084 NaN
2012-10-31 306.424497 NaN
2012-11-30 307.557154 NaN
2012-12-31 308.404771 299.649905
2013-01-31 309.503169 NaN
2013-02-28 311.581691 NaN
2013-03-31 315.642943 NaN
2013-04-30 321.662612 NaN
2013-05-31 328.279935 NaN
2013-06-30 333.565899 NaN
[462 rows x 2 columns]
我們有很多NaN
數(shù)據(jù)峰锁。 如果我們?nèi)∠欣L圖代碼的注釋萎馅,會發(fā)生什么? 原來虹蒋,我們沒有得到包含NaN
數(shù)據(jù)的圖表糜芳! 這是一個偷懶,所以首先我們想魄衅,好吧峭竣,讓我們丟掉所有有NaN
數(shù)據(jù)的行。 這僅僅是出于教程的目的晃虫。 在這個例子中皆撩,這將是一個非常糟糕的主意。 相反哲银,你會想要做我們原來做的事情扛吞,這是為重采樣數(shù)據(jù)創(chuàng)建一個新的數(shù)據(jù)幀。 并不意味著你可以總是這樣做荆责,但在這種情況下滥比,你可以這樣做。 無論如何做院,讓我們刪除包含任何na
數(shù)據(jù)的所有行盲泛。 這很簡單:
HPI_data.dropna(inplace=True)
print(HPI_data[['TX','TX1yr']])
TX TX1yr
Date
1975-12-31 6.336776 4.559105
1976-12-31 15.000798 11.954152
1977-12-31 30.434104 23.518179
1978-12-31 51.029953 41.978042
1979-12-31 75.975953 64.700665
1980-12-31 89.979964 85.147662
1981-12-31 108.121926 99.016599
1982-12-31 118.210559 114.589927
1983-12-31 127.233791 122.676432
1984-12-31 133.599958 131.033359
1985-12-31 132.576673 133.847016
1986-12-31 126.581048 131.627647
1987-12-31 109.829893 119.373827
1988-12-31 104.602726 107.930502
1989-12-31 108.485926 107.311348
1990-12-31 109.082279 108.727174
1991-12-31 114.471725 113.142303
1992-12-31 121.427564 119.650162
1993-12-31 129.817931 127.009907
1994-12-31 135.119413 134.279735
1995-12-31 141.774551 139.197583
1996-12-31 146.991204 145.786792
1997-12-31 155.855049 152.109010
1998-12-31 170.625043 164.595301
1999-12-31 188.404171 181.149544
2000-12-31 206.579848 199.952853
2001-12-31 217.747701 215.692648
2002-12-31 230.161877 226.962219
2003-12-31 236.946005 235.459053
2004-12-31 248.031552 245.225988
2005-12-31 267.728910 260.589093
2006-12-31 288.009470 281.876293
2007-12-31 296.154296 298.094138
2008-12-31 288.081223 296.999508
2009-12-31 291.665787 292.160280
2010-12-31 281.678911 291.357967
2011-12-31 282.384836 284.001507
2012-12-31 308.404771 299.649905
沒有帶有缺失數(shù)據(jù)的行了!
現(xiàn)在我們可以繪制它:
fig = plt.figure()
ax1 = plt.subplot2grid((1,1), (0,0))
HPI_data = pd.read_pickle('fiddy_states3.pickle')
HPI_data['TX1yr'] = HPI_data['TX'].resample('A')
HPI_data.dropna(inplace=True)
print(HPI_data[['TX','TX1yr']])
HPI_data['TX'].plot(ax=ax1)
HPI_data['TX1yr'].plot(color='k',ax=ax1)
plt.legend().remove()
plt.show()
https://pythonprogramming.net/static/images/pandas/pandas-remove-na-example.png
好的键耕,太好了寺滚。 現(xiàn)在只是出于教程的目的屈雄,我們?nèi)绾尉帉懘a村视,只在整行是NaN
時才刪除行?
HPI_data.dropna(how='all',inplace=True)
對于how
參數(shù)棚亩,你可以選擇any
或all
蓖议。 all
需要該行中的所有數(shù)據(jù)為NaN
虏杰,才能將其刪除。 你也可以選擇any
勒虾,然后設(shè)置一個閾值纺阔。 該閾值將要求存在許多非na
值,才能接受該行修然。 更多信息笛钝,請參閱dropna
的Pandas
文檔。
好吧愕宋,所以這就是dropna
玻靡,接下來我們可以填充它。 使用填充中贝,我們又有兩個主要的選擇囤捻,是向前還是向后。 另一個選擇是僅僅替換數(shù)據(jù)邻寿,但我們稱這是一個單獨(dú)的選擇蝎土。 碰巧相同函數(shù)可以用于實現(xiàn)它,fillna
绣否。
修改我們原來的代碼塊誊涯,主要改變:
HPI_data.fillna(method='ffill',inplace=True)
變?yōu)椋?/p>
fig = plt.figure()
ax1 = plt.subplot2grid((1,1), (0,0))
HPI_data = pd.read_pickle('fiddy_states3.pickle')
HPI_data['TX1yr'] = HPI_data['TX'].resample('A')
HPI_data.fillna(method='ffill',inplace=True)
HPI_data.dropna(inplace=True)
print(HPI_data[['TX','TX1yr']])
HPI_data['TX'].plot(ax=ax1)
HPI_data['TX1yr'].plot(color='k',ax=ax1)
plt.legend().remove()
plt.show()
https://pythonprogramming.net/static/images/pandas/pandas-fill-na-example.png
ffill
,或者“前向填充”所做的就是蒜撮,將數(shù)據(jù)向前掃描暴构,填充到缺失的數(shù)據(jù)中。 把它看作是一個掃描動作段磨,其中你可以從過去獲取數(shù)據(jù)取逾,將其轉(zhuǎn)移到缺失的數(shù)據(jù)中。 任何缺失數(shù)據(jù)的情況都會以最近的非缺失數(shù)據(jù)填入薇溃。 Bfill
或后向填充是相反的:
HPI_data.fillna(method='bfill',inplace=True)
https://pythonprogramming.net/static/images/pandas/pandas-bfill-example.png
這從未來獲取數(shù)據(jù)菌赖,并向后掃描來填充缺失。
現(xiàn)在沐序,對于最后一種方法琉用,替換數(shù)據(jù)。 NaN
數(shù)據(jù)是相對毫無價值的數(shù)據(jù)策幼,但它可以污染我們的其余數(shù)據(jù)邑时。以機(jī)器學(xué)習(xí)為例,其中每行是一個特征集特姐,每列是一個特征晶丘。數(shù)據(jù)對我們來說價值非常高,如果我們有大量的NaN
數(shù)據(jù),那么放棄所有的數(shù)據(jù)是非常糟糕的浅浮。出于這個原因沫浆,你可能實際上使用替換。對于大多數(shù)機(jī)器學(xué)習(xí)分類器來說滚秩,最終的異常值通常被忽略為自己的數(shù)據(jù)點(diǎn)专执。正因為如此,很多人會做的是獲取任何NaN
數(shù)據(jù)郁油,并用-99999
的值代替它本股。這是因為在數(shù)據(jù)預(yù)處理之后,通常需要將所有特征轉(zhuǎn)換為-1
到1
的范圍桐腌。對于幾乎任何分類器來說拄显,數(shù)據(jù)點(diǎn)-99999
是一個明顯的異常值。但是NaN
的數(shù)據(jù)案站,根本無法處理躬审!因此,我們可以通過執(zhí)行以下操作來替換數(shù)據(jù):
HPI_data.fillna(value=-99999,inplace=True)
現(xiàn)在嚼吞,在我們的情況下盒件,這是一個毫無用處的操作,但它確實在某些形式的數(shù)據(jù)分析中占有一席之地舱禽。
現(xiàn)在我們已經(jīng)介紹了處理缺失數(shù)據(jù)的基礎(chǔ)知識,我們準(zhǔn)備繼續(xù)恩沽。 在下一篇教程中誊稚,我們將討論另一種平滑數(shù)據(jù)的方法,這些方法可以讓我們保留月度數(shù)據(jù):滾動統(tǒng)計量罗心。 這對于平滑我們的數(shù)據(jù)里伯,以及在它上面收集一些基本的統(tǒng)計量是有用的。
十一渤闷、滾動統(tǒng)計量
歡迎閱讀另一個 Python 和 Pandas 數(shù)據(jù)分析系列教程疾瓮,這里面我們成為了房地產(chǎn)大亨。在本教程中飒箭,我們將討論各種滾動統(tǒng)計量在我們的數(shù)據(jù)幀中的應(yīng)用狼电。
其中較受歡迎的滾動統(tǒng)計量是移動均值。這需要一個移動的時間窗口弦蹂,并計算該時間段的均值作為當(dāng)前值肩碟。在我們的情況下,我們有月度數(shù)據(jù)凸椿。所以 10 移動均值就是當(dāng)前值加上前 9 個月的數(shù)據(jù)的均值削祈,之后我們的月度數(shù)據(jù)將有 10 個移動均值。Pandas 做這個是非常快的髓抑。Pandas 帶有一些預(yù)先制作的滾動統(tǒng)計量咙崎,但也有一個叫做rolling_apply
。這使我們可以編寫我們自己的函數(shù)吨拍,接受窗口數(shù)據(jù)并應(yīng)用我們想要的任何合理邏輯叙凡。這意味著,即使Pandas 沒有處理你想要的東西的正式函數(shù)密末,他們已經(jīng)覆蓋了你握爷,讓你準(zhǔn)確地編寫你需要的東西。讓我們從基本的移動均值開始严里,或者 Pandas 叫它rolling_mean
新啼。你可以查看 Pandas 文檔中的所有移動/滾動統(tǒng)計量。
前面的教程涵蓋了我們的起始腳本刹碾,如下所示:
import Quandl
import pandas as pd
import pickle
import matplotlib.pyplot as plt
from matplotlib import style
style.use('fivethirtyeight')
# Not necessary, I just do this so I do not show my API key.
api_key = open('quandlapikey.txt','r').read()
def state_list():
fiddy_states = pd.read_html('https://simple.wikipedia.org/wiki/List_of_U.S._states')
return fiddy_states[0][0][1:]
def grab_initial_state_data():
states = state_list()
main_df = pd.DataFrame()
for abbv in states:
query = "FMAC/HPI_"+str(abbv)
df = Quandl.get(query, authtoken=api_key)
print(query)
df[abbv] = (df[abbv]-df[abbv][0]) / df[abbv][0] * 100.0
print(df.head())
if main_df.empty:
main_df = df
else:
main_df = main_df.join(df)
pickle_out = open('fiddy_states3.pickle','wb')
pickle.dump(main_df, pickle_out)
pickle_out.close()
def HPI_Benchmark():
df = Quandl.get("FMAC/HPI_USA", authtoken=api_key)
df["United States"] = (df["United States"]-df["United States"][0]) / df["United States"][0] * 100.0
return df
fig = plt.figure()
ax1 = plt.subplot2grid((1,1), (0,0))
HPI_data = pd.read_pickle('fiddy_states3.pickle')
plt.show()
現(xiàn)在燥撞,在定義HPI_data
之后,我們可以添加一些新的數(shù)據(jù)迷帜,如下所示:
HPI_data['TX12MA'] = pd.rolling_mean(HPI_data['TX'], 12)
這給了我們一個新列物舒,我們命名為TX12MA
來表示得克薩斯和 12 移動平均。 我們將這個應(yīng)用到pd.rolling_mean()
中戏锹,該函數(shù)接受 2 個主要參數(shù)冠胯,我們正在應(yīng)用的數(shù)據(jù)以及我們打算執(zhí)行的周期/窗口。
https://pythonprogramming.net/static/images/pandas/pandas-rolling-mean-tutorial.png
使用滾動統(tǒng)計量锦针,開頭將生成NaN
數(shù)據(jù)荠察。 考慮執(zhí)行 10 移動均值。 在#3
行奈搜,我們根本沒有 10 個以前的數(shù)據(jù)點(diǎn)悉盆。 因此會形成NaN
數(shù)據(jù)。 你可以把它留在那里馋吗,或者用前面的教程中的dropna()
來刪除它焕盟。
另一個有趣的是滾動標(biāo)準(zhǔn)差。 我們需要把它放在自己的圖表上宏粤,但我們可以這樣做:
ig = plt.figure()
ax1 = plt.subplot2grid((2,1), (0,0))
ax2 = plt.subplot2grid((2,1), (1,0), sharex=ax1)
HPI_data = pd.read_pickle('fiddy_states3.pickle')
HPI_data['TX12MA'] = pd.rolling_mean(HPI_data['TX'], 12)
HPI_data['TX12STD'] = pd.rolling_std(HPI_data['TX'], 12)
HPI_data['TX'].plot(ax=ax1)
HPI_data['TX12MA'].plot(ax=ax1)
HPI_data['TX12STD'].plot(ax=ax2)
plt.show()
https://pythonprogramming.net/static/images/pandas/pandas-rolling-standard-deviation-tutorial.png
這里發(fā)生了一些事情脚翘,讓我們快速談?wù)撍鼈儭?/p>
ax1 = plt.subplot2grid((2,1), (0,0))
ax2 = plt.subplot2grid((2,1), (1,0), sharex=ax1)
在這里,我們定義了第二個軸商架,并改變我們的大小堰怨。 我們說這個子圖的網(wǎng)格是2×1
(高 2,寬 1)蛇摸,那么我們說ax1
從0,0
開始备图,ax2
從1,0
開始,它和ax1
共享x
軸。 這使我們可以放大一個圖形揽涮,而另一個圖形也放大到同一點(diǎn)抠藕。 仍然對 Matplotlib 感到困惑? 使用 Matplotlib 系列教程查看完整的數(shù)據(jù)可視化蒋困。
接下來盾似,我們計算移動標(biāo)準(zhǔn)差:
HPI_data['TX12STD'] = pd.rolling_std(HPI_data['TX'], 12)
然后,我們繪制所有東西雪标。
另一個有趣的可視化是比較得克薩斯HPI
與整體HPI
零院。 然后計算他們兩個之間的滾動相關(guān)性蛛芥。 假設(shè)是劝枣,相關(guān)性下降時鲫构,很快就會出現(xiàn)逆轉(zhuǎn)牍颈。 如果相關(guān)性下降,這意味著得克薩斯HPI
和整體HPI
是不一致的俏险。 比方說蠢古,美國整體的HPI
在上面玩焰,TX_HPI
在下面產(chǎn)生分歧逆粹。 在這種情況下募疮,我們可能會選擇投資德克薩斯州的房地產(chǎn)。 另一個選擇是使用TX
和另一個高度相關(guān)的區(qū)域僻弹。 例如阿浓,德克薩斯州與阿拉斯加的相關(guān)系數(shù)為0.983235
。 讓我們看看我們的計劃看起來怎么樣奢方。 最后一塊應(yīng)該現(xiàn)在看起來是這樣:
fig = plt.figure()
ax1 = plt.subplot2grid((2,1), (0,0))
ax2 = plt.subplot2grid((2,1), (1,0), sharex=ax1)
HPI_data = pd.read_pickle('fiddy_states3.pickle')
TX_AK_12corr = pd.rolling_corr(HPI_data['TX'], HPI_data['AK'], 12)
HPI_data['TX'].plot(ax=ax1, label="TX HPI")
HPI_data['AK'].plot(ax=ax1, label="AK HPI")
ax1.legend(loc=4)
TX_AK_12corr.plot(ax=ax2)
plt.show()
https://pythonprogramming.net/static/images/pandas/pandas-rolling-statistics-tutorial.png
每當(dāng)相關(guān)性下降時搔扁,你理論上應(yīng)該在上漲的地方出售房地產(chǎn),然后你應(yīng)該購買正在下降的地區(qū)的房地產(chǎn)蟋字。這個想法是,這兩個地區(qū)是高度相關(guān)的扭勉,我們可以非常確信鹊奖,相關(guān)性最終會回到0.98
左右。因此涂炎,當(dāng)相關(guān)系數(shù)為-0.5
時忠聚,我們可以非常有把握地決定采取這樣的行動,因為結(jié)果可能是下面的結(jié)果之一:HPI
永遠(yuǎn)是這樣的分歧唱捣,永遠(yuǎn)不會恢復(fù)(不太可能)两蟀,下降的地區(qū)上升并遇到上升的地區(qū),這樣我們贏了震缭,上升的地區(qū)下降并遇到另一個下降的地區(qū)赂毯,在這種情況下,我們發(fā)了一筆大財,或者雙方都重新一致党涕,在這種情況下烦感,我們肯定贏了。 HPI
不可能完全背離這些市場膛堤。我們可以清楚地看到手趣,這完全不會發(fā)生,我們有 40 年的數(shù)據(jù)支持肥荔。
在接下來的教程中绿渣,我們將討論異常值檢測,不管是錯誤與否燕耿,還包括了如何處理這些數(shù)據(jù)背后的一些哲理中符。
十二、將比較操作應(yīng)用于數(shù)據(jù)幀
歡迎閱讀 Python 和 Pandas 數(shù)據(jù)分析系列教程第 12 部分缸棵。 在本教程中舟茶,我們將簡要討論如何處理錯誤/異常數(shù)據(jù)。 僅僅因為數(shù)據(jù)是異常的堵第,并不意味著它是錯誤的吧凉。 很多時候,離群數(shù)據(jù)點(diǎn)可以使一個假設(shè)無效踏志,所以去除它的必要性可能會很高阀捅,但這不是我們在這里討論的。
錯誤的異常值是多少针余? 我喜歡使用的一個例子是測量諸如橋梁之類的波動饲鄙。 由于橋梁承載重量,他們可以移動一點(diǎn)圆雁。 在風(fēng)浪中忍级,可以稍微擺動一下,就會有一些自然的運(yùn)動伪朽。 隨著時間的推移轴咱,支撐力量減弱,橋梁可能會移動太多烈涮,最終需要加固朴肺。 也許我們有一個不斷測量橋梁高度波動的系統(tǒng)。
https://pythonprogramming.net/static/images/pandas/pandas-distance-sensor-example.png
一些距離傳感器使用激光坚洽,另一些則反彈聲波戈稿。 無論你想假裝我們正在使用哪個,都沒關(guān)系讶舰。 我們會假裝聲波鞍盗。 它們的工作方式是從觸發(fā)器發(fā)出聲波需了,然后在前面物體處反彈,返回到接收器橡疼。 從這里開始援所,整個操作發(fā)生的時間被考慮在內(nèi)。 由于音速是一個常數(shù)欣除,我們可以從這個過程的時間推斷出聲波傳播的距離住拭。 問題是,這只衡量聲波傳播了多遠(yuǎn)历帚。 例如他們?nèi)チ藰蛄汉捅巢刻显溃瑳]有 100% 的確定性。 也許一片樹葉在測量時掉落挽牢,并在信號回到接收器之前反彈了信號谱煤,誰知道呢。 比方說禽拔,舉個例子刘离,你有以下的橋梁讀數(shù):
bridge_height = {'meters':[10.26, 10.31, 10.27, 10.22, 10.23, 6212.42, 10.28, 10.25, 10.31]}
我們可以可視化:
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import style
style.use('fivethirtyeight')
bridge_height = {'meters':[10.26, 10.31, 10.27, 10.22, 10.23, 6212.42, 10.28, 10.25, 10.31]}
df = pd.DataFrame(bridge_height)
df.plot()
plt.show()
那么橋是不是被外星人動過了? 由于此后我們有更多的正常讀數(shù)睹栖,6212.42
更可能是一個不好的讀數(shù)硫惕。 我們可以直觀地看出這是一個異常,但是我們怎么能通過我們的程序檢測到這一點(diǎn)野来?
我們意識到這是一個異常值恼除,因為它與其他價有很大的不同,以及它比其他任何值都突然上升或下降的事實曼氛。 聽起來我們可以僅僅應(yīng)用標(biāo)準(zhǔn)差豁辉。 我們用它來自動檢測這個不好的讀數(shù)。
df['STD'] = pd.rolling_std(df['meters'], 2)
print(df)
meters STD
0 10.26 NaN
1 10.31 0.035355
2 10.27 0.028284
3 10.22 0.035355
4 10.23 0.007071
5 6212.42 4385.610607
6 10.28 4385.575252
7 10.25 0.021213
8 10.31 0.042426
注:兩個數(shù)的標(biāo)準(zhǔn)差就是
|a - b|/2
舀患。
接下來徽级,我們可以獲得整個集合的標(biāo)準(zhǔn)差,如:
df_std = df.describe()
print(df_std)
df_std = df.describe()['meters']['std']
print(df_std)
meters STD
count 9.000000 8.000000
mean 699.394444 1096.419446
std 2067.384584 2030.121949
min 10.220000 0.007071
25% 10.250000 0.026517
50% 10.270000 0.035355
75% 10.310000 1096.425633
max 6212.420000 4385.610607
2067.38458357
首先聊浅,我們得到所有的描述灰追。 顯示了大部分,所以你看我們?nèi)绾翁幚頂?shù)據(jù)狗超。 然后,我們直接查看米的標(biāo)準(zhǔn)差朴下,這是 2067 和一些變化努咐。 這是一個相當(dāng)高的數(shù)字,但仍然遠(yuǎn)低于主要波動(4385)的標(biāo)準(zhǔn)差殴胧。 現(xiàn)在渗稍,我們可以遍歷并刪除所有標(biāo)準(zhǔn)差高于這個值的數(shù)據(jù)佩迟。
這使我們能夠?qū)W習(xí)一項新技能:在邏輯上修改數(shù)據(jù)幀! 我們可以這樣做:
df = df[ (df['STD'] < df_std) ]
print(df)
meters STD
1 10.31 0.035355
2 10.27 0.028284
3 10.22 0.035355
4 10.23 0.007071
7 10.25 0.021213
8 10.31 0.042426
之后我們可以繪制所有東西:
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import style
style.use('fivethirtyeight')
bridge_height = {'meters':[10.26, 10.31, 10.27, 10.22, 10.23, 6212.42, 10.28, 10.25, 10.31]}
df = pd.DataFrame(bridge_height)
df['STD'] = pd.rolling_std(df['meters'], 2)
print(df)
df_std = df.describe()
print(df_std)
df_std = df.describe()['meters']['std']
print(df_std)
df = df[ (df['STD'] < df_std) ]
print(df)
df['meters'].plot()
plt.show()
輸出:
https://pythonprogramming.net/static/images/pandas/pandas-outlier-detection-tutorial.png
我們剛學(xué)到的新行是df = df[ (df['STD'] < df_std) ]
竿屹。 這是如何工作的报强? 首先,我們一開始重新定義df
拱燃。 我們說現(xiàn)在df
等于df
秉溉,其中df['STD']
小于我們之前計算的整體df_std
。 因此碗誉,這里唯一剩下的數(shù)據(jù)將是標(biāo)準(zhǔn)差小于 2067 的數(shù)據(jù)召嘶。
再次,當(dāng)我們知道這些數(shù)據(jù)錯誤的哮缺,我們應(yīng)該刪除它弄跌。 因為數(shù)據(jù)不“適合”你而刪除,幾乎總是一個壞主意尝苇。
十三铛只、30 年抵押貸款利率
歡迎閱讀 Python 和 Pandas 數(shù)據(jù)分析第 13 部分,以房地產(chǎn)投資為例糠溜。到了這里淳玩,我們已經(jīng)了解了 Pandas 能提供給我們的東西,我們會在這里面對一些挑戰(zhàn)诵冒!正如我們到目前為止所介紹的那樣凯肋,我們可以根據(jù)高度相關(guān)的州對之間的分歧,做出風(fēng)險相對較低的投資汽馋,可能做得很好侮东。稍后我們將介紹測試這個策略,但是現(xiàn)在讓我們來看看獲取包含房屋價值的其他必要數(shù)據(jù):利率”荆現(xiàn)在悄雅,抵押貸款利率有很多不同的類型,既有利息收入铁蹈,也有貸款的時間表宽闲。這些年來,意見有所不同握牧,根據(jù)目前的市場情況容诬,是否需要 10 年,15 年或 30 年的抵押貸款沿腰。那么你必須考慮你是否想要可調(diào)整的利率览徒,或者在半路上再決定為你的房子付費(fèi)的方式。
在數(shù)據(jù)的最后颂龙,所有這些數(shù)據(jù)都是有限的习蓬,但最終可能會有點(diǎn)過于嘈雜∨κ玻現(xiàn)在,讓我們簡單介紹一下 30 年的傳統(tǒng)抵押貸款利率《愕穑現(xiàn)在芦缰,這個數(shù)據(jù)應(yīng)該與房價指數(shù)(HPI)非常負(fù)相關(guān)。在這個低嗎之前枫慷,我會自動假設(shè)并期望相關(guān)性不會非常強(qiáng)让蕾,就像高于 90% 的HPI
相關(guān)性,它肯定低于-0.9
流礁,而且應(yīng)該比-0.5
大涕俗。利率當(dāng)然很重要,但是整個HPI
的相關(guān)性非常強(qiáng)神帅,因為這些數(shù)據(jù)非常相似再姑。利率當(dāng)然是相關(guān)的,但并不像其他HPI
值或美國HPI
那樣直接找御。
首先元镀,我們抓取這些數(shù)據(jù)。我們將開始創(chuàng)建一個新的函數(shù):
def mortgage_30y():
df = Quandl.get("FMAC/MORTG", trim_start="1975-01-01", authtoken=api_key)
df["Value"] = (df["Value"]-df["Value"][0]) / df["Value"][0] * 100.0
print(df.head())
return df
mortgage_30y()
Value
Date
1975-01-01 0.000000
1975-02-01 -3.393425
1975-03-01 -5.620361
1975-04-01 -6.468717
1975-05-01 -5.514316
這里有幾個要點(diǎn)霎桅。 首先栖疑,注意添加到Quandl.get()
的新參數(shù),它是trim_start
滔驶。 這使我們能夠在特定的日期啟動數(shù)據(jù)遇革。 我們之所以選擇 1975 年 1 月 1 日,是因為那是我們的房價指數(shù)數(shù)據(jù)開始的時候揭糕。 從這里萝快,我們打印數(shù)據(jù)頭部,我們有了第一個問題:這是某月的第一天著角,而不是月底揪漩。 當(dāng)我們將這個數(shù)據(jù)幀加入到其他數(shù)據(jù)幀時,這會造成麻煩吏口。 那么現(xiàn)在怎么辦奄容? 我們已經(jīng)學(xué)會了如何重新采樣,如果我們只是使用M
來進(jìn)行典型的重新采樣产徊,這意味著月末昂勒,會怎么樣呢? 也許這會把數(shù)據(jù)移動到第 31 天舟铜,因為這個月只有一個值叁怪。
def mortgage_30y():
df = Quandl.get("FMAC/MORTG", trim_start="1975-01-01", authtoken=api_key)
df["Value"] = (df["Value"]-df["Value"][0]) / df["Value"][0] * 100.0
df=df.resample('M')
print(df.head())
return df
mortgage_30y()
Value
Date
1975-01-31 NaN
1975-02-28 NaN
1975-03-31 NaN
1975-04-30 NaN
1975-05-31 NaN
好吧,這并沒有那么好深滚。 我們可能需要多個數(shù)據(jù)點(diǎn)才能進(jìn)行計算奕谭,那么我們該怎么做? 我們可以嘗試調(diào)整日期列或別的痴荐,或者我們可以做一些黑魔法血柳。 如果我們只是按天抽樣呢? 如果我們這樣做的話生兆,那么這個數(shù)字將在整個月份里持續(xù)重復(fù)难捌。 然后,我們可以重采樣到月末鸦难,然后一切都應(yīng)該有效根吁。
def mortgage_30y():
df = Quandl.get("FMAC/MORTG", trim_start="1975-01-01", authtoken=api_key)
df["Value"] = (df["Value"]-df["Value"][0]) / df["Value"][0] * 100.0
df=df.resample('1D')
df=df.resample('M')
print(df.head())
return df
mortgage_30y()
Value
Date
1975-01-31 0.000000
1975-02-28 -3.393425
1975-03-31 -5.620361
1975-04-30 -6.468717
1975-05-31 -5.514316
我們贏了! 接下來合蔽,我們可以獲取所有的數(shù)據(jù)击敌,將這個新的數(shù)據(jù)集添加到數(shù)據(jù)幀中,現(xiàn)在我們真的上路了拴事。 為了防止你剛剛加入我們沃斤,或者你半路走丟了,這里是目前為止的代碼:
import Quandl
import pandas as pd
import pickle
import matplotlib.pyplot as plt
from matplotlib import style
style.use('fivethirtyeight')
# Not necessary, I just do this so I do not show my API key.
api_key = open('quandlapikey.txt','r').read()
def state_list():
fiddy_states = pd.read_html('https://simple.wikipedia.org/wiki/List_of_U.S._states')
return fiddy_states[0][0][1:]
def grab_initial_state_data():
states = state_list()
main_df = pd.DataFrame()
for abbv in states:
query = "FMAC/HPI_"+str(abbv)
df = Quandl.get(query, authtoken=api_key)
print(query)
df[abbv] = (df[abbv]-df[abbv][0]) / df[abbv][0] * 100.0
print(df.head())
if main_df.empty:
main_df = df
else:
main_df = main_df.join(df)
pickle_out = open('fiddy_states3.pickle','wb')
pickle.dump(main_df, pickle_out)
pickle_out.close()
def HPI_Benchmark():
df = Quandl.get("FMAC/HPI_USA", authtoken=api_key)
df["United States"] = (df["United States"]-df["United States"][0]) / df["United States"][0] * 100.0
return df
def mortgage_30y():
df = Quandl.get("FMAC/MORTG", trim_start="1975-01-01", authtoken=api_key)
df["Value"] = (df["Value"]-df["Value"][0]) / df["Value"][0] * 100.0
df=df.resample('1D')
df=df.resample('M')
return df
現(xiàn)在我們可以做一些事情刃宵,例如:
HPI_data = pd.read_pickle('fiddy_states3.pickle')
m30 = mortgage_30y()
HPI_Bench = HPI_Benchmark()
m30.columns=['M30']
HPI = HPI_Bench.join(m30)
print(HPI.head())
United States M30
Date
1975-01-31 0.000000 0.000000
1975-02-28 0.594738 -3.393425
1975-03-31 1.575473 -5.620361
1975-04-30 2.867177 -6.468717
1975-05-31 3.698896 -5.514316
下面衡瓶,我們可以立即計算一個簡單的相關(guān)性:
print(HPI.corr())
United States M30
United States 1.000000 -0.740009
M30 -0.740009 1.000000
這是我們的預(yù)期。 -0.74
是相當(dāng)強(qiáng)的負(fù)值牲证。 很明顯哮针,各州之間的聯(lián)系并不是很好,但這顯然是一個有用的指標(biāo)坦袍。 接下來十厢,我們可以在所有州上檢查這個指標(biāo):
state_HPI_M30 = HPI_data.join(m30)
print(state_HPI_M30.corr())
AL AK AZ AR CA CO CT \
AL 1.000000 0.944603 0.927361 0.994896 0.935970 0.979352 0.953724
AK 0.944603 1.000000 0.893904 0.965830 0.900621 0.949834 0.896395
AZ 0.927361 0.893904 1.000000 0.923786 0.973546 0.911422 0.917500
AR 0.994896 0.965830 0.923786 1.000000 0.935364 0.985934 0.948341
CA 0.935970 0.900621 0.973546 0.935364 1.000000 0.924982 0.956495
CO 0.979352 0.949834 0.911422 0.985934 0.924982 1.000000 0.917129
CT 0.953724 0.896395 0.917500 0.948341 0.956495 0.917129 1.000000
DE 0.980566 0.939196 0.942273 0.975830 0.970232 0.949517 0.981177
FL 0.918544 0.887891 0.994007 0.915989 0.987200 0.905126 0.926364
GA 0.973562 0.880261 0.939715 0.960708 0.943928 0.959500 0.948500
HI 0.946054 0.930520 0.902554 0.947022 0.937704 0.903461 0.938974
ID 0.982868 0.944004 0.959193 0.977372 0.944342 0.960975 0.923099
IL 0.984782 0.905512 0.947396 0.973761 0.963858 0.968552 0.955033
IN 0.981189 0.889734 0.881542 0.973259 0.901154 0.971416 0.919696
IA 0.985516 0.943740 0.894524 0.987919 0.914199 0.991455 0.913788
KS 0.990774 0.957236 0.910948 0.995230 0.926872 0.994866 0.936523
KY 0.994311 0.938125 0.900888 0.992903 0.923429 0.987097 0.941114
LA 0.967232 0.990506 0.909534 0.982454 0.911742 0.972703 0.907456
ME 0.972693 0.935850 0.923797 0.972573 0.965251 0.951917 0.989180
MD 0.964917 0.943384 0.960836 0.964943 0.983677 0.940805 0.969170
MA 0.966242 0.919842 0.921782 0.966962 0.962672 0.959294 0.986178
MI 0.891205 0.745697 0.848602 0.873314 0.861772 0.900040 0.843032
MN 0.971967 0.926352 0.952359 0.972338 0.970661 0.983120 0.945521
MS 0.996089 0.962494 0.927354 0.997443 0.932752 0.985298 0.945831
MO 0.992706 0.933201 0.938680 0.989672 0.955317 0.985194 0.961364
MT 0.977030 0.976840 0.916000 0.983822 0.923950 0.971516 0.917663
NE 0.988030 0.941229 0.896688 0.990868 0.912736 0.992179 0.920409
NV 0.858538 0.785404 0.965617 0.846968 0.948143 0.837757 0.866554
NH 0.953366 0.907236 0.932992 0.952882 0.969574 0.941555 0.990066
NJ 0.968837 0.934392 0.943698 0.967477 0.975258 0.944460 0.989845
NM 0.992118 0.967777 0.934744 0.993195 0.934720 0.968001 0.946073
NY 0.973984 0.940310 0.921126 0.973972 0.959543 0.949474 0.989576
NC 0.998383 0.934841 0.915403 0.991863 0.928632 0.977069 0.956074
ND 0.936510 0.973971 0.840705 0.957838 0.867096 0.942225 0.882938
OH 0.966598 0.855223 0.883396 0.954128 0.901842 0.957527 0.911510
OK 0.944903 0.984550 0.881332 0.967316 0.882199 0.960694 0.879854
OR 0.981180 0.948190 0.949089 0.978144 0.944542 0.971110 0.916942
PA 0.985357 0.946184 0.915914 0.983651 0.950621 0.956316 0.975324
RI 0.950261 0.897159 0.943350 0.945984 0.984298 0.926362 0.988351
SC 0.998603 0.945949 0.929591 0.994117 0.942524 0.980911 0.959591
SD 0.983878 0.966573 0.889405 0.990832 0.911188 0.984463 0.924295
TN 0.998285 0.946858 0.919056 0.995949 0.931616 0.983089 0.953009
TX 0.963876 0.983235 0.892276 0.981413 0.902571 0.970795 0.919415
UT 0.983987 0.951873 0.926676 0.982867 0.909573 0.974909 0.900908
VT 0.975210 0.952370 0.909242 0.977904 0.949225 0.951388 0.973716
VA 0.972236 0.956925 0.950839 0.975683 0.977028 0.954801 0.970366
WA 0.988253 0.948562 0.950262 0.982877 0.956434 0.968816 0.941987
WV 0.984364 0.964846 0.907797 0.990264 0.924300 0.979467 0.925198
WI 0.990190 0.930548 0.927619 0.985818 0.943768 0.987609 0.936340
WY 0.944600 0.983109 0.892255 0.960336 0.897551 0.950113 0.880035
M30 -0.762343 -0.678591 -0.614237 -0.747709 -0.680250 -0.747269 -0.726121
DE FL GA ... TN TX UT \
AL 0.980566 0.918544 0.973562 ... 0.998285 0.963876 0.983987
AK 0.939196 0.887891 0.880261 ... 0.946858 0.983235 0.951873
AZ 0.942273 0.994007 0.939715 ... 0.919056 0.892276 0.926676
AR 0.975830 0.915989 0.960708 ... 0.995949 0.981413 0.982867
CA 0.970232 0.987200 0.943928 ... 0.931616 0.902571 0.909573
CO 0.949517 0.905126 0.959500 ... 0.983089 0.970795 0.974909
CT 0.981177 0.926364 0.948500 ... 0.953009 0.919415 0.900908
DE 1.000000 0.947876 0.954346 ... 0.977213 0.943323 0.952441
FL 0.947876 1.000000 0.933753 ... 0.910359 0.881164 0.908197
GA 0.954346 0.933753 1.000000 ... 0.970564 0.920372 0.943421
HI 0.976226 0.909336 0.887794 ... 0.941823 0.916708 0.925630
ID 0.971421 0.947140 0.953024 ... 0.976012 0.943472 0.989533
IL 0.978133 0.948851 0.986683 ... 0.980145 0.925778 0.961563
IN 0.941916 0.873664 0.972737 ... 0.982888 0.928735 0.956452
IA 0.954993 0.888359 0.948792 ... 0.987924 0.959989 0.980798
KS 0.964387 0.903659 0.961825 ... 0.993486 0.978622 0.980113
KY 0.968469 0.895461 0.966719 ... 0.996549 0.961847 0.975918
LA 0.949931 0.899010 0.911625 ... 0.968690 0.989803 0.975590
ME 0.993413 0.932706 0.949576 ... 0.973697 0.946992 0.935993
MD 0.993728 0.968700 0.938240 ... 0.960881 0.935619 0.945962
MA 0.978758 0.931237 0.964604 ... 0.969053 0.943613 0.923883
MI 0.846668 0.846085 0.952179 ... 0.891484 0.806632 0.855976
MN 0.966800 0.955992 0.976933 ... 0.970940 0.944605 0.955689
MS 0.975673 0.917084 0.963318 ... 0.996444 0.977670 0.987812
MO 0.978316 0.936293 0.986001 ... 0.991835 0.958853 0.969655
MT 0.968166 0.909331 0.917504 ... 0.976586 0.967914 0.985605
NE 0.951875 0.888425 0.962706 ... 0.991270 0.966743 0.976138
NV 0.881209 0.971601 0.911678 ... 0.845672 0.791177 0.841324
NH 0.975576 0.943501 0.959112 ... 0.954165 0.930112 0.908947
NJ 0.995132 0.952767 0.950385 ... 0.967025 0.940268 0.935497
NM 0.980594 0.925001 0.949564 ... 0.989390 0.972216 0.986413
NY 0.993814 0.928749 0.947804 ... 0.974697 0.950417 0.937078
NC 0.977472 0.906887 0.976190 ... 0.998354 0.959839 0.976901
ND 0.926355 0.833816 0.849962 ... 0.944451 0.964373 0.942833
OH 0.927542 0.878248 0.980012 ... 0.966237 0.900707 0.935392
OK 0.917902 0.868255 0.893142 ... 0.947590 0.992422 0.951925
OR 0.969869 0.940983 0.945712 ... 0.977083 0.943652 0.991080
PA 0.994948 0.919264 0.946609 ... 0.984959 0.954439 0.956809
RI 0.984731 0.959567 0.951973 ... 0.947561 0.907964 0.906497
SC 0.983353 0.922779 0.976778 ... 0.997851 0.966682 0.979527
SD 0.963422 0.883479 0.931010 ... 0.987597 0.973825 0.979387
TN 0.977213 0.910359 0.970564 ... 1.000000 0.967678 0.982384
TX 0.943323 0.881164 0.920372 ... 0.967678 1.000000 0.956718
UT 0.952441 0.908197 0.943421 ... 0.982384 0.956718 1.000000
VT 0.992088 0.914969 0.929674 ... 0.976577 0.955538 0.947708
VA 0.994223 0.957210 0.939416 ... 0.970906 0.952162 0.953655
WA 0.985085 0.945027 0.956455 ... 0.983588 0.950234 0.984835
WV 0.968813 0.901690 0.931330 ... 0.985509 0.967845 0.983636
WI 0.970690 0.925943 0.974086 ... 0.988615 0.946572 0.977972
WY 0.938938 0.884962 0.869454 ... 0.945079 0.963628 0.965801
M30 -0.758073 -0.627997 -0.706512 ... -0.770422 -0.669410 -0.737147
VT VA WA WV WI WY M30
AL 0.975210 0.972236 0.988253 0.984364 0.990190 0.944600 -0.762343
AK 0.952370 0.956925 0.948562 0.964846 0.930548 0.983109 -0.678591
AZ 0.909242 0.950839 0.950262 0.907797 0.927619 0.892255 -0.614237
AR 0.977904 0.975683 0.982877 0.990264 0.985818 0.960336 -0.747709
CA 0.949225 0.977028 0.956434 0.924300 0.943768 0.897551 -0.680250
CO 0.951388 0.954801 0.968816 0.979467 0.987609 0.950113 -0.747269
CT 0.973716 0.970366 0.941987 0.925198 0.936340 0.880035 -0.726121
DE 0.992088 0.994223 0.985085 0.968813 0.970690 0.938938 -0.758073
FL 0.914969 0.957210 0.945027 0.901690 0.925943 0.884962 -0.627997
GA 0.929674 0.939416 0.956455 0.931330 0.974086 0.869454 -0.706512
HI 0.979103 0.976083 0.963950 0.952790 0.928536 0.935530 -0.755064
ID 0.955898 0.970393 0.994442 0.975239 0.977441 0.956742 -0.721927
IL 0.958711 0.968271 0.982702 0.962100 0.992079 0.911345 -0.753583
IN 0.937365 0.928187 0.955000 0.958981 0.982614 0.889497 -0.773100
IA 0.960204 0.955724 0.976571 0.990479 0.991509 0.955104 -0.785584
KS 0.967734 0.964949 0.977117 0.988007 0.989477 0.956913 -0.748138
KY 0.970702 0.962244 0.977386 0.985453 0.992035 0.938804 -0.785726
LA 0.958907 0.962746 0.967991 0.982913 0.957145 0.988894 -0.683956
ME 0.993570 0.990376 0.969212 0.963035 0.963999 0.929516 -0.769778
MD 0.983851 0.997558 0.981974 0.962220 0.960073 0.945807 -0.729642
MA 0.975046 0.975432 0.953441 0.947520 0.964247 0.904811 -0.758192
MI 0.817081 0.828781 0.862245 0.843538 0.918028 0.741663 -0.686146
MN 0.952722 0.969721 0.973082 0.961230 0.987026 0.927507 -0.723314
MS 0.974975 0.973635 0.986430 0.989047 0.986738 0.961005 -0.750756
MO 0.968741 0.972720 0.980907 0.974606 0.993691 0.930004 -0.747344
MT 0.974065 0.976197 0.985994 0.993622 0.972195 0.990517 -0.756735
NE 0.954657 0.949766 0.969023 0.981915 0.988942 0.938583 -0.761330
NV 0.828018 0.882206 0.882127 0.820529 0.874777 0.779155 -0.543798
NH 0.966338 0.972531 0.944892 0.930573 0.949941 0.892414 -0.722957
NJ 0.987844 0.992944 0.971273 0.956438 0.960854 0.928928 -0.743508
NM 0.977351 0.978702 0.988594 0.985877 0.976586 0.966689 -0.729704
NY 0.994142 0.989544 0.968541 0.962209 0.961359 0.929946 -0.770619
NC 0.973354 0.965901 0.981436 0.978326 0.987338 0.931717 -0.770820
ND 0.957772 0.944229 0.935840 0.972698 0.921882 0.977003 -0.763102
OH 0.912974 0.910193 0.939052 0.933308 0.974849 0.852217 -0.753133
OK 0.930105 0.933030 0.937180 0.959298 0.932422 0.969641 -0.621887
OR 0.959889 0.973285 0.995502 0.984262 0.984121 0.968156 -0.749370
PA 0.997231 0.989277 0.982052 0.978963 0.972162 0.945319 -0.779589
RI 0.970213 0.980550 0.953760 0.930845 0.950360 0.890562 -0.732558
SC 0.977946 0.975200 0.987828 0.982315 0.989425 0.943358 -0.754808
SD 0.976071 0.967219 0.976170 0.994328 0.979649 0.971496 -0.794906
TN 0.976577 0.970906 0.983588 0.985509 0.988615 0.945079 -0.770422
TX 0.955538 0.952162 0.950234 0.967845 0.946572 0.963628 -0.669410
UT 0.947708 0.953655 0.984835 0.983636 0.977972 0.965801 -0.737147
VT 1.000000 0.991347 0.975016 0.976666 0.961824 0.951637 -0.779342
VA 0.991347 1.000000 0.983402 0.973592 0.966393 0.956771 -0.745763
WA 0.975016 0.983402 1.000000 0.984210 0.984955 0.962198 -0.750646
WV 0.976666 0.973592 0.984210 1.000000 0.981398 0.977070 -0.770068
WI 0.961824 0.966393 0.984955 0.981398 1.000000 0.939200 -0.776679
WY 0.951637 0.956771 0.962198 0.977070 0.939200 1.000000 -0.702034
M30 -0.779342 -0.745763 -0.750646 -0.770068 -0.776679 -0.702034 1.000000
[51 rows x 51 columns]
我們感興趣的主要一列是 M30 與其它東西的對比,所以我們這樣做:
print(state_HPI_M30.corr()['M30'])
AL -0.762343
AK -0.678591
AZ -0.614237
AR -0.747709
CA -0.680250
CO -0.747269
CT -0.726121
DE -0.758073
FL -0.627997
GA -0.706512
HI -0.755064
ID -0.721927
IL -0.753583
IN -0.773100
IA -0.785584
KS -0.748138
KY -0.785726
LA -0.683956
ME -0.769778
MD -0.729642
MA -0.758192
MI -0.686146
MN -0.723314
MS -0.750756
MO -0.747344
MT -0.756735
NE -0.761330
NV -0.543798
NH -0.722957
NJ -0.743508
NM -0.729704
NY -0.770619
NC -0.770820
ND -0.763102
OH -0.753133
OK -0.621887
OR -0.749370
PA -0.779589
RI -0.732558
SC -0.754808
SD -0.794906
TN -0.770422
TX -0.669410
UT -0.737147
VT -0.779342
VA -0.745763
WA -0.750646
WV -0.770068
WI -0.776679
WY -0.702034
M30 1.000000
Name: M30, dtype: float64
看起來亞利桑那(AZ)的負(fù)相關(guān)最弱键闺,為-0.614237
寿烟。 我們可以通過以下方式快速獲取更多數(shù)據(jù):
print(state_HPI_M30.corr()['M30'].describe())
count 51.000000
mean -0.699445
std 0.247709
min -0.794906
25% -0.762723
50% -0.748138
75% -0.722442
max 1.000000
Name: M30, dtype: float64
這里的均值在-0.7
以下,這與我們以前的發(fā)現(xiàn)非常一致辛燥,這里并沒有太多的延展筛武。這在邏輯上應(yīng)該是顯而易見的,但數(shù)據(jù)明確地反映了挎塌,抵押貸款利率在房價中起著重要的作用徘六。到目前為止,我所發(fā)現(xiàn)的有趣之處是榴都,我們所看到的變化是多么的微小待锈。有一些州存在分歧,但不是很多嘴高。大多數(shù)州嚴(yán)格保持在一條直線上竿音,帶有非常簡單的規(guī)則和屎。在深入局部地區(qū)之前,我們的第三個主要因素春瞬,是整體經(jīng)濟(jì)柴信。從這里開始,我們可以開始關(guān)注州的人口統(tǒng)計數(shù)據(jù)宽气,同時我們深入到縣甚至社區(qū)随常。但是,我想知道萄涯,鑒于迄今為止這樣可靠的值绪氛,我們已經(jīng)很容易為HPI
制定一個公式。如果不是一個基本的公式涝影,我懷疑我們可以在一個隨機(jī)森林分類器中使用這些數(shù)據(jù)枣察,并做得很好。現(xiàn)在袄琳,讓我們繼續(xù)看看整體經(jīng)濟(jì)询件。我們希望看到0.5
以上的相關(guān)性。我們在下一個教程中介紹一下唆樊。
十四宛琅、添加其它經(jīng)濟(jì)指標(biāo)
大家好,歡迎閱讀我們的 Python 和 Pandas 數(shù)據(jù)分析(和地產(chǎn)投資)系列教程的第14部分逗旁。我們在這里已經(jīng)走了很長一段路嘿辟,我們想要在這里采取的下一個,最后一大步驟是研究宏觀經(jīng)濟(jì)指標(biāo)片效,看看它們對房價或HPI
的影響红伦。
SP500 (股票市場)和國內(nèi)生產(chǎn)總值(GDP)是兩個主要的經(jīng)濟(jì)指標(biāo)。我懷疑 SP500 比國內(nèi)生產(chǎn)總值相關(guān)性更高淀衣,但 GDP 總體來說是一個較好的整體經(jīng)濟(jì)指標(biāo)昙读,所以我可能是錯的。以及膨桥,我懷疑在這里可能有價值的宏觀指標(biāo)是失業(yè)率蛮浑。如果你失業(yè)了,你可能不能得到抵押貸款只嚣。我們會驗證沮稚。我們已經(jīng)完成了添加更多數(shù)據(jù)點(diǎn)的流程,所以把你拖入這個過程沒有多少意義。但是會有一個新的東西需要注意。在HPI_Benchmark()
函數(shù)中贯底,我們將United States
列更改為US_HPI
棘幸。當(dāng)我們現(xiàn)在引入其他值時盛杰,這會更有意義挽荡。
對于國內(nèi)生產(chǎn)總值,我找不到一個包含所有時間的東西饶唤。我相信你可以使用這個數(shù)據(jù)在某個地方徐伐,甚至在 Quandl 上找到一個數(shù)據(jù)集。有時你必須做一些挖掘募狂。我也很難找到一個很好的長期月失業(yè)率。我確實找到了一個失業(yè)率水平角雷,但我們真的不僅僅想要百分比/比例祸穷,否則我們需要把失業(yè)水平除以人口。如果我們確定失業(yè)率值得擁有勺三,我們可以這樣做雷滚,但我們需要首先處理我們得到的東西。
將 Pandas 和 Quandl 代碼更新為 2016 年 8 月 1 日的最新版本:
import quandl
import pandas as pd
import pickle
import matplotlib.pyplot as plt
from matplotlib import style
style.use('fivethirtyeight')
# Not necessary, I just do this so I do not show my API key.
api_key = open('quandlapikey.txt','r').read()
def state_list():
fiddy_states = pd.read_html('https://simple.wikipedia.org/wiki/List_of_U.S._states')
return fiddy_states[0][0][1:]
def grab_initial_state_data():
states = state_list()
main_df = pd.DataFrame()
for abbv in states:
query = "FMAC/HPI_"+str(abbv)
df = quandl.get(query, authtoken=api_key)
df.rename(columns={'Value': abbv}, inplace=True)
df[abbv] = (df[abbv]-df[abbv][0]) / df[abbv][0] * 100.0
print(df.head())
if main_df.empty:
main_df = df
else:
main_df = main_df.join(df)
pickle_out = open('fiddy_states3.pickle','wb')
pickle.dump(main_df, pickle_out)
pickle_out.close()
def HPI_Benchmark():
df = quandl.get("FMAC/HPI_USA", authtoken=api_key)
df["United States"] = (df["Value"]-df["Value"][0]) / df["Value"][0] * 100.0
df.rename(columns={'United States':'US_HPI'}, inplace=True)
return df
def mortgage_30y():
df = quandl.get("FMAC/MORTG", trim_start="1975-01-01", authtoken=api_key)
df["Value"] = (df["Value"]-df["Value"][0]) / df["Value"][0] * 100.0
df=df.resample('1D').mean()
df=df.resample('M').mean()
return df
def sp500_data():
df = quandl.get("YAHOO/INDEX_GSPC", trim_start="1975-01-01", authtoken=api_key)
df["Adjusted Close"] = (df["Adjusted Close"]-df["Adjusted Close"][0]) / df["Adjusted Close"][0] * 100.0
df=df.resample('M').mean()
df.rename(columns={'Adjusted Close':'sp500'}, inplace=True)
df = df['sp500']
return df
def gdp_data():
df = quandl.get("BCB/4385", trim_start="1975-01-01", authtoken=api_key)
df["Value"] = (df["Value"]-df["Value"][0]) / df["Value"][0] * 100.0
df=df.resample('M').mean()
df.rename(columns={'Value':'GDP'}, inplace=True)
df = df['GDP']
return df
def us_unemployment():
df = quandl.get("ECPI/JOB_G", trim_start="1975-01-01", authtoken=api_key)
df["Unemployment Rate"] = (df["Unemployment Rate"]-df["Unemployment Rate"][0]) / df["Unemployment Rate"][0] * 100.0
df=df.resample('1D').mean()
df=df.resample('M').mean()
return df
grab_initial_state_data()
HPI_data = pd.read_pickle('fiddy_states3.pickle')
m30 = mortgage_30y()
sp500 = sp500_data()
gdp = gdp_data()
HPI_Bench = HPI_Benchmark()
unemployment = us_unemployment()
m30.columns=['M30']
HPI = HPI_Bench.join([m30,sp500,gdp,unemployment])
HPI.dropna(inplace=True)
print(HPI.corr())
US_HPI M30 sp500 GDP Unemployment Rate
US_HPI 1.000000 -0.738364 0.738395 0.543507 0.033925
M30 -0.738364 1.000000 -0.625544 -0.714845 -0.395650
sp500 0.738395 -0.625544 1.000000 0.470505 -0.262561
GDP 0.543507 -0.714845 0.470505 1.000000 0.551058
Unemployment Rate 0.033925 -0.395650 -0.262561 0.551058 1.000000
在這里吗坚,我們看到 SP500 與US_HPI
強(qiáng)相關(guān)祈远,30 年抵押貸款利率顯然也是如此。其次商源,GDP 不是最可靠的车份。這是正值,但我更像看> 70
的東西牡彻。最后扫沼,失業(yè)率更低。幾乎中立庄吼!我對此感到非常驚訝缎除。有了這些信息,我想說 SP500 和 30 年抵押貸款利率可以用來預(yù)測房屋市場总寻。這很好器罐,因為這些數(shù)字都可以不間斷地獲得。我很驚訝地看到 SP500 與 HPI 之間的 0.738 相關(guān)性渐行。大多數(shù)人認(rèn)為股票和住房是多元化的轰坊。很多人都記得房地產(chǎn)危機(jī),而且既然股市和房屋都一起下跌殊轴,可能就不會有這樣的感覺了衰倦,但是傳統(tǒng)的智慧依然表明人們通過持有股票和房地產(chǎn)來多樣化。 40 年的數(shù)據(jù)似乎并不完全一致旁理。
向前看樊零,我提倡考慮宏觀市場,使用美國房價指數(shù)(US_HPI),30 年抵押貸款利率(M30)和標(biāo)準(zhǔn)普爾 500 指數(shù)(SP500)驻襟。
我們將使用這些值來涵蓋本系列的最后一部分:結(jié)合其他主要數(shù)據(jù)科學(xué)庫夺艰。我們這里,我們將結(jié)合 Scikit Learn沉衣,看看我們是否能預(yù)測 HPI 的合理軌跡郁副。這樣做只是一個開始,但是之后要求我們使用類似的策略來繼續(xù)下去豌习,直到我們實際購買的房產(chǎn)的微觀層面存谎。無論如何,我們還是億萬富翁肥隆,生活是美好的既荚。在我們繼續(xù)之前,我們將最后一次運(yùn)行這個代碼栋艳,將其保存到一個pickle
中恰聘,這樣我們就不需要繼續(xù)運(yùn)行代碼了。為了保存到pickle
吸占,只需把它放在腳本的末尾:
HPI.to_pickle('HPI.pickle')
十五晴叨、滾動應(yīng)用和預(yù)測函數(shù)
這個 Python 和 Pandas 數(shù)據(jù)分析教程將涵蓋兩個主題。首先矾屯,在機(jī)器學(xué)習(xí)的背景下兼蕊,我們需要一種方法,為我們的數(shù)據(jù)創(chuàng)建“標(biāo)簽”问拘。其次遍略,我們將介紹 Pandas 的映射函數(shù)和滾動應(yīng)用功能。
創(chuàng)建標(biāo)簽對監(jiān)督式機(jī)器學(xué)習(xí)過程至關(guān)重要骤坐,因為它用于“教給”或訓(xùn)練機(jī)器與特征相關(guān)的正確答案绪杏。
Pandas 數(shù)據(jù)幀映射函數(shù)到非常有用,可用于編寫自定義公式纽绍,將其應(yīng)用于整個數(shù)據(jù)幀蕾久,特定列或創(chuàng)建新列。如果你回想一下拌夏,我們生成了一些新列僧著,比如df['Column2'] = df['Column1']*1.5
,等等障簿。如果你想創(chuàng)建更多的邏輯密集操作盹愚,但是,你會希望寫一個函數(shù)站故。我們將展示如何實現(xiàn)它皆怕。
由于映射函數(shù)是兩種方法之一毅舆,用戶可以極大地定制 Pandas 可以做的事情,我們也會涵蓋第二種主要方式愈腾,即使用rolling_apply
憋活。這使我們可以應(yīng)用函數(shù)的移動窗口。我們剛剛寫了一個移動平均函數(shù)虱黄,但是你可以做任何你想要的悦即。
首先,我們有一些代碼:
import Quandl
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import style
import numpy as np
from statistics import mean
style.use('fivethirtyeight')
housing_data = pd.read_pickle('HPI.pickle')
housing_data = housing_data.pct_change()
首先橱乱,我們要加載數(shù)據(jù)集辜梳,然后將所有列轉(zhuǎn)換為百分比變化。 這將幫助我們規(guī)范所有的數(shù)據(jù)泳叠。
下面:
housing_data.replace([np.inf, -np.inf], np.nan, inplace=True)
housing_data['US_HPI_future'] = housing_data['United States'].shift(-1)
在這里冗美,我們先用nan
值代替無窮值。 接下來析二,我們創(chuàng)建一個新的列,其中包含未來的 HPI节预。 我們可以用一個新的方法來實現(xiàn):.shift()
叶摄。 這種方法將會改變有問題的列。 移動-1
意味著我們正在向下移動安拟,所以下一個點(diǎn)的值會移動回來蛤吓。 這是我們的方法,用于快速獲得當(dāng)前值糠赦,以及下一時期同一行上的值会傲,用于比較。
接下來拙泽,在百分比變化應(yīng)用和移動中淌山,我們有一些NaN
數(shù)據(jù),所以我們需要做以下工作:
new_column = list(map( function_to_map, parameter1, parameter2, ... ))
這就是它的一切顾瞻,你可以繼續(xù)添加更多的參數(shù)泼疑。
print(housing_data.head())
AL AK AZ AR CA CO \
Date
1990-03-31 0.003628 0.062548 -0.003033 0.005570 0.007152 0.000963
1990-04-30 0.006277 0.095081 -0.002126 0.005257 0.005569 -0.000318
1990-05-31 0.007421 0.112105 0.001513 0.005635 0.002409 0.004512
1990-06-30 0.004930 0.100642 0.004353 0.006238 0.003569 0.007884
1990-07-31 0.000436 0.067064 0.003322 0.006173 0.004351 0.004374
CT DE FL GA ... WV WI \
Date ...
1990-03-31 -0.009234 0.002786 -0.001259 -0.007290 ... 0.013441 0.015638
1990-04-30 -0.010818 0.000074 0.002675 -0.002477 ... 0.015765 0.015926
1990-05-31 -0.010963 -0.000692 0.004656 0.002808 ... 0.017085 0.012106
1990-06-30 -0.007302 -0.001542 0.003710 0.002857 ... 0.016638 0.010545
1990-07-31 -0.003439 -0.004680 0.003116 0.002276 ... 0.011129 0.009425
WY United States M30 Unemployment Rate GDP \
Date
1990-03-31 0.009831 0.004019 0.090909 0.035714 -0.234375
1990-04-30 0.016868 0.004957 0.119048 -0.068966 4.265306
1990-05-31 0.026130 0.005260 0.117021 0.000000 -1.092539
1990-06-30 0.029359 0.005118 -0.304762 0.074074 3.115183
1990-07-31 0.023640 0.003516 -0.164384 -0.103448 0.441476
sp500 US_HPI_future label
Date
1990-03-31 0.030790 0.004957 1
1990-04-30 -0.001070 0.005260 1
1990-05-31 0.045054 0.005118 0
1990-06-30 0.036200 0.003516 0
1990-07-31 -0.001226 0.000395 0
[5 rows x 57 columns]
接下來,讓我們展示一個自定義方式荷荤,來應(yīng)用移動窗口函數(shù)退渗。 我們僅僅執(zhí)行一個簡單的移動平均示例:
def moving_average(values):
ma = mean(values)
return ma
這就是我們的功能,請注意蕴纳,我們只是傳遞了values
參數(shù)会油。 我們不需要編寫任何類型的“窗口”或“時間框架”處理,Pandas 將為我們處理古毛。
現(xiàn)在翻翩,你可以使用rolling_apply
:
housing_data['ma_apply_example'] = pd.rolling_apply(housing_data['M30'], 10, moving_average)
print(housing_data.tail())
AL AK AZ AR CA CO \
Date
2011-07-31 -0.003545 -0.004337 0.002217 0.003215 -0.005579 0.004794
2011-08-31 -0.006886 -0.007139 0.004283 0.000275 -0.007782 0.001058
2011-09-30 -0.011103 -0.007609 0.003190 0.000505 -0.006537 -0.004569
2011-10-31 -0.013189 -0.007754 0.000541 0.001059 -0.005390 -0.009231
2011-11-30 -0.008055 -0.006551 0.005119 -0.000856 -0.003570 -0.010812
CT DE FL GA ... \
Date ...
2011-07-31 -0.002806 -0.001084 -0.001531 -0.003036 ...
2011-08-31 -0.010243 -0.002133 0.001438 -0.006488 ...
2011-09-30 -0.012240 -0.004171 0.002307 -0.013116 ...
2011-10-31 -0.013075 -0.006204 -0.001566 -0.021542 ...
2011-11-30 -0.012776 -0.008252 -0.006211 -0.022371 ...
WI WY United States M30 Unemployment Rate \
Date
2011-07-31 -0.002068 0.001897 -0.000756 -0.008130 0.000000
2011-08-31 -0.006729 -0.002080 -0.005243 0.057377 0.000000
2011-09-30 -0.011075 -0.006769 -0.007180 0.031008 -0.100000
2011-10-31 -0.015025 -0.008818 -0.008293 0.007519 -0.111111
2011-11-30 -0.014445 -0.006293 -0.008541 0.014925 -0.250000
GDP sp500 US_HPI_future label ma_apply_example
Date
2011-07-31 0.024865 0.031137 -0.005243 0 -0.003390
2011-08-31 0.022862 -0.111461 -0.007180 0 -0.000015
2011-09-30 -0.039361 -0.010247 -0.008293 0 0.004432
2011-10-31 0.018059 0.030206 -0.008541 0 0.013176
2011-11-30 0.000562 0.016886 -0.009340 0 0.015728
[5 rows x 58 columns]
十六、Scikit Learn 交互
在這個 Pandas 和 Python 數(shù)據(jù)分析系列教程中,我們將展示如何快速將 Pandas 數(shù)據(jù)集轉(zhuǎn)換為數(shù)據(jù)幀体斩,并將其轉(zhuǎn)換為 numpy 數(shù)組梭稚,然后可以傳給各種其他 Python 數(shù)據(jù)分析模塊。 我們要在這里使用的例子是 Scikit-Learn絮吵,也就是 SKlearn弧烤。 為了這樣做,你需要安裝它:
pip install sklearn
從這里開始蹬敲,我們幾乎已經(jīng)完成了暇昂。 對于機(jī)器學(xué)習(xí)來說,至少在監(jiān)督的形式下伴嗡,我們只需要幾件事情急波。 首先,我們需要“特征”瘪校。 在我們的例子中澄暮,特征是像當(dāng)前的 HPI,也許是 GDP 等等阱扬。 之后你需要“標(biāo)簽”泣懊。 標(biāo)簽被分配到特征“集”,其中對于任何給定的“標(biāo)簽”麻惶,特征集是任何 GDP馍刮,HPI 等等的集合。 這里佛南,我們的標(biāo)簽是 1 或 0苛白,其中 1 表示 HPI 未來增加薇芝,0 表示沒有逼争。
可能不用說仍翰,但我會提醒你:你不應(yīng)該將“未來的 HPI”列包括為一個特征。 如果你這樣做狞换,機(jī)器學(xué)習(xí)算法將認(rèn)識到這一點(diǎn)适荣,并且準(zhǔn)確性非常高闰歪,在現(xiàn)實世界中不可能實際有用库倘。
前面教程的代碼是這樣的:
import Quandl
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import style
import numpy as np
from statistics import mean
style.use('fivethirtyeight')
# Not necessary, I just do this so I do not show my API key.
api_key = open('quandlapikey.txt','r').read()
def create_labels(cur_hpi, fut_hpi):
if fut_hpi > cur_hpi:
return 1
else:
return 0
def moving_average(values):
return mean(values)
housing_data = pd.read_pickle('HPI.pickle')
housing_data = housing_data.pct_change()
housing_data.replace([np.inf, -np.inf], np.nan, inplace=True)
housing_data['US_HPI_future'] = housing_data['United States'].shift(-1)
housing_data.dropna(inplace=True)
#print(housing_data[['US_HPI_future','United States']].head())
housing_data['label'] = list(map(create_labels,housing_data['United States'], housing_data['US_HPI_future']))
#print(housing_data.head())
housing_data['ma_apply_example'] = pd.rolling_apply(housing_data['M30'], 10, moving_average)
print(housing_data.tail())
下面临扮,我們打算添加一些新的導(dǎo)入:
from sklearn import svm, preprocessing, cross_validation
我們將使用 svm(支持向量機(jī))庫作為我們的機(jī)器學(xué)習(xí)分類器。 預(yù)處理用來調(diào)整我們的數(shù)據(jù)集教翩。 通常情況下杆勇,如果你的特征介于 -1 和 1 之間,則機(jī)器學(xué)習(xí)會更精確一些饱亿。 這并不意味著永遠(yuǎn)是真的蚜退,檢查是否縮放總是一個好主意,以便萬無一失彪笼。 cross_validation
是一個庫钻注,我們將用來創(chuàng)建我們的訓(xùn)練和測試集。 這只是一個很好的方法配猫,可以自動隨機(jī)抽取數(shù)據(jù)队寇,用于訓(xùn)練和測試。
現(xiàn)在章姓,我們可以創(chuàng)建我們的特征和標(biāo)簽來進(jìn)行訓(xùn)練/測試:
X = np.array(housing_data.drop(['label','US_HPI_future'], 1))
X = preprocessing.scale(X)
一般來說佳遣,對于特征和標(biāo)簽识埋,你有了X
,y
零渐。 大寫字母X
用來表示一個特征集窒舟。 y
是標(biāo)簽。 我們在這里所做的是诵盼,將特征集定義為housing_data
數(shù)據(jù)幀內(nèi)容的 numpy 數(shù)組(這只是將數(shù)據(jù)幀的內(nèi)容轉(zhuǎn)換為多維數(shù)組)惠豺,同時刪除了label
和US_HPI_future
列。
y = np.array(housing_data['label'])
現(xiàn)在我們的標(biāo)簽已經(jīng)定義好了风宁,我們已經(jīng)準(zhǔn)備好洁墙,將我們的數(shù)據(jù)分解成訓(xùn)練和測試集。 我們可以自己做戒财,但是我們將使用之前的cross_validation
導(dǎo)入:
注:
cross_validation
會打亂數(shù)據(jù)热监,最好不要在時序數(shù)據(jù)上使用這個方法,反之應(yīng)該以一個位置分割數(shù)據(jù)饮寞。
X_train, X_test, y_train, y_test = cross_validation.train_test_split(X, y, test_size=0.2)
它所做的就是將你的特征(X
)和標(biāo)簽(y
)隨機(jī)分解為訓(xùn)練和測試集孝扛。 正如你所看到的,返回值是訓(xùn)練集特征幽崩,測試集特征苦始,訓(xùn)練集標(biāo)簽和測試集標(biāo)簽。 然后慌申,我們將這些解構(gòu)到X_train
陌选,X_test
,y_train
蹄溉,y_test
中柠贤。 cross_validation.train_test_split
接受你的特征和標(biāo)簽作為參數(shù),然后你也可以指定測試集的大欣噻汀(test_size
),我們已經(jīng)指定為 0.2邻吭,意思是 20%餐弱。
現(xiàn)在,我們可以建立我們打算使用的分類器:
clf = svm.SVC(kernel='linear')
在這個例子中囱晴,我們將使用線性核的支持向量分類器膏蚓。 在這里更多了解sklearn.svm.SVC
。
接下來畸写,我們要訓(xùn)練我們的分類器:
clf.fit(X_train, y_train)
最后驮瞧,我們從這里可以繼續(xù)并進(jìn)行預(yù)測,但是讓我們來測試分類器在已知數(shù)據(jù)上的準(zhǔn)確性:
print(clf.score(X_test, y_test))
0.792452830189
我的平均準(zhǔn)確度約為 70%枯芬。 你可能會得到不同的結(jié)果论笔。 有許多地方用于機(jī)器學(xué)習(xí)調(diào)參采郎。 我們可以改變一些默認(rèn)參數(shù),我們可以查看一些其他算法狂魔,但是現(xiàn)在這樣做還不錯蒜埋。
感謝各位的捐助,你們的慷慨是我繼續(xù)的動力最楷。