python输入一组数据、进行简单的统计_《利用Python进行数据分析》学习笔记——第二章(3)...
1880-2010年間全美嬰兒姓名
用pandas.read_csv加載.txt文件
圖2.1 用read_csv加載.txt文件
DataFrame.names1880中只有births這一列是int型,所有在使用sum()函數(shù)他似乎是會(huì)默認(rèn)使用births列進(jìn)行分組(groupby):
圖2.2 默認(rèn)對(duì)births列進(jìn)行分組
讀取所有數(shù)據(jù),并組裝到一個(gè)DataFrame中,再加上一個(gè)year字段:
圖2.3 讀取所有數(shù)據(jù)
range(1880,2011)是因?yàn)閞ange是左閉右開的,而2010是最后一個(gè)有效統(tǒng)計(jì)年度。
frame['year']=year,當(dāng)沒有指定行的話,那么整個(gè)的'year'列都會(huì)賦予相同的值。
將所有數(shù)據(jù)整合到單個(gè)DataFrame中:
圖2.4 將所有數(shù)據(jù)整合到單個(gè)DataFrame中
concat默認(rèn)按行將多個(gè)DataFrame組合到一起,pieces是由多個(gè)DataFrame組合成的list,所以這些單個(gè)的數(shù)據(jù)而具有各自的索引(index),因此在組合的時(shí)候我們需要忽視現(xiàn)在的索引(index),然后concat會(huì)為這個(gè)新的組合的DataFrame設(shè)置新的索引(index)。
如果不設(shè)置ignore_index=True這個(gè)參數(shù)的話,也不會(huì)報(bào)錯(cuò),那樣的話這個(gè)DataFrame就會(huì)有相同的index。那么,當(dāng)我們根據(jù)這個(gè)index進(jìn)行索引的時(shí)候就會(huì)將這些擁有相同index的數(shù)據(jù)全部提取出來:
圖2.4 沒有設(shè)置ignore_index=True的索引結(jié)果
可以看到正好每個(gè)年份都有一個(gè)相同的index
利用pivot_table在year和sex級(jí)別上進(jìn)行聚合:
圖2.5 數(shù)據(jù)透視表
.tail()是輸出最后的5行,.head()的話則是開始的5行。下面是用groupby進(jìn)行分組的方式:
圖2.6? groupby進(jìn)行分組
用groupby的話要注意使用.unstack(),不要讓數(shù)據(jù)堆疊在一起。
畫出圖像:
圖2.7 按性別和年度統(tǒng)計(jì)的總出生數(shù)
插入prop列,用于存放指定名字的嬰兒數(shù)相對(duì)于總出生數(shù)的比例:
圖2.8 插入prop列
‘用于存放指定名字的嬰兒數(shù)相對(duì)于總出生數(shù)的比例’,這句話我一開始沒有理解,所以對(duì)其中定義的add_prop(group)函數(shù)的計(jì)算結(jié)果感到疑惑:
圖2.9 prop的總數(shù)
按照我對(duì)這句話最初的理解,prop的總數(shù)應(yīng)該為1才對(duì),而結(jié)果是262(sum進(jìn)行浮點(diǎn)計(jì)算會(huì)丟失精度,因而結(jié)果應(yīng)該是262)。
那么按照這個(gè)理解,這句話具體的含義應(yīng)該是‘指定名字且相同性別的嬰兒相對(duì)于同一年份嬰兒的總出生數(shù)的比例’(感覺好像有點(diǎn)長,不知道還有沒更簡潔的表達(dá)方式):
圖2.10 分組的prop總和
其實(shí)還是對(duì)groupby這個(gè)函數(shù)的理解不到位,不然其實(shí)通過代碼是可以輕易的反推出題意的。
檢查分組總計(jì)值:
圖2.11 分組總計(jì)值為1
取出每對(duì)sex/year組合的前1000個(gè)名字:
圖2.12?取出每對(duì)sex/year組合的前1000個(gè)名字
這里除了書上的兩種方法,為了讓它看起來更簡潔,就把方法1的函數(shù)用lambda代替了。
分析命名趨勢(shì)
有了完整的數(shù)據(jù)集和剛才生成的top1000數(shù)據(jù)集,我們就可以開始分析各種命名趨勢(shì)了。首先將前1000個(gè)名字分為男女兩個(gè)部分:
圖2.13 布爾型數(shù)組索引
生成一張按year和name統(tǒng)計(jì)的總出生數(shù)的數(shù)據(jù)透視表:
圖2.14 按year和name統(tǒng)計(jì)的總出生數(shù)透視表
這里出現(xiàn)了警告,大概意思應(yīng)該是'year'同時(shí)具有兩個(gè)屬性,index level (索引水平)和 column label(列標(biāo)簽),我一開始以為是pivot_table的參數(shù)問題,所以用groupby也試了一下,發(fā)現(xiàn)依舊出現(xiàn)這樣的警告,也不知道怎么消除。但是問題應(yīng)該不大,畢竟是可以運(yùn)行的。
用plot方法繪制名字的曲線圖:
圖2.15 plot方法繪圖
這里的subplots參數(shù)分成若干子圖,figsize圖的尺寸,grid網(wǎng)格。生成的圖像:
圖2.16 幾個(gè)男孩和女孩名字隨時(shí)間變化的使用數(shù)量
評(píng)估命名多樣性的增長
圖2.16所反映的降低情況可能意味著父母愿意給小孩起常見的名字越來越少。這個(gè)假設(shè)可以從數(shù)據(jù)中得到驗(yàn)證。
一個(gè)辦法是計(jì)算最流行的1000個(gè)名字所占比例:
按year和sex進(jìn)行聚合并繪圖:
圖2.17 分性別統(tǒng)計(jì)的前1000個(gè)名字在總出生人數(shù)中的比例
通過前1000項(xiàng)的比例降低,可以得知名字的多樣性出現(xiàn)了增長。
另一個(gè)辦法是計(jì)算占總出生人數(shù)前50%的不同名字的數(shù)量:
圖2.18 計(jì)算cumsum,確定0.5的位置
cumnum()計(jì)算前n項(xiàng)的累加和,所以用在這里時(shí)要注意排序。
searchsorted()尋找某個(gè)數(shù)應(yīng)該插在數(shù)組的什么位置上,返回值是Index,也就是說0.5應(yīng)該插在索引為116的位置,又由于index是從0開始,所以0.5應(yīng)作為第116+1=117個(gè)數(shù)添加進(jìn)去,這里可以看一下index=115和Index=116的數(shù)分別是多少:
圖2.19 查看Index=115 和index=116的數(shù)據(jù)
這里一開始腦子沒有轉(zhuǎn)過來,還在想0.5明明在二者之間,為什么他應(yīng)該放在117這個(gè)位置。這個(gè)問題就和‘小明跑步比賽中超過了第一名,現(xiàn)在他是第幾名’一樣傻。。。
與1900年做比較:
圖2.20 1900年0.5的位置
用一個(gè)函數(shù)計(jì)算各分組的'searcheasored(0.5)+1'值:
圖2.21 計(jì)算各分組'searcheasored(0.5)+1'? 的值
這里我犯了一個(gè)很大錯(cuò)誤,書上的程序是“diversity = diversity.unstack('sex')”,這里我寫的時(shí)候自作聰明寫成了“diversity.unstack()”,當(dāng)然在這里的輸出圖表結(jié)果是不影響的。但是,在后面繪圖的時(shí)候,由于'sex'堆疊在一起,所以輸出的圖和我想要的是有區(qū)別的。并且還花費(fèi)了我大量時(shí)間查找錯(cuò)誤。
另外從這里輸出的DataFrame中的數(shù)據(jù)帶有括號(hào),而書上的結(jié)果是沒有的,這應(yīng)該又是python3和python2區(qū)別了。而且如果沒注意到這個(gè)問題,繪圖時(shí)就會(huì)報(bào)錯(cuò)。
這個(gè)簡單函數(shù)還是嘗試用lambda寫一下:
圖2.22 用lambda函數(shù)計(jì)算'searchsorted(0.5)+1'的值
繪制圖表:
先看一下沒堆疊的錯(cuò)誤的圖:
圖2.23 'sex'堆疊的圖表
當(dāng)然如果要是完全按照書上來的話是不會(huì)出現(xiàn)這樣的問題的(python3還是有其他問題的)
上面說了,DataFrame的結(jié)果和書上有區(qū)別(帶括號(hào)),當(dāng)我們用這個(gè)直接用這個(gè)結(jié)果繪圖的時(shí)候會(huì)報(bào)這樣的錯(cuò):
圖2.24 TypeError
類型錯(cuò)誤,說我們的DataFrame里沒有數(shù)值類型(numeric)
所以先看一下那個(gè)帶括號(hào)的數(shù)據(jù)是什么類型:
圖2.25 ndarray類型數(shù)據(jù)
所以為了將圖像正常輸出來,就要用類型轉(zhuǎn)換astype(int):
圖2.26 正常輸出的按年度統(tǒng)計(jì)的密度表
從圖中可以看出,女孩名字的多樣性總是比男孩高,而且還在變得越來越高
“最后一個(gè)字母”的變革
為了了解男孩名字在最后一個(gè)字母上的分布發(fā)生變化,我首先將全部出生數(shù)據(jù)在年度、性別以及及末字母上進(jìn)行了聚合:
圖2.27 末字母聚合
這里的map將傳入的函數(shù)依次作用到序列的每個(gè)元素,并把結(jié)果作為新的Iterator返回。
選出具有一定代表性的三年:
圖2.29 具有代表性的三年
按總出生數(shù)對(duì)該表進(jìn)行規(guī)范化處理,以計(jì)算各性別各末字母占總出生人數(shù)的比例:
圖2.30 表規(guī)范化處理
這里沒有和書上一樣用數(shù)據(jù)類型轉(zhuǎn)換,發(fā)現(xiàn)結(jié)果還是一樣的,所以先在這去掉,如果后面出現(xiàn)問題,可以更好的理解這里轉(zhuǎn)換的意義。
生成各年度各性別的條形圖:
圖2.31 程序
圖2.32 男孩女孩名字中各個(gè)末字母的比例
fig、axes分別是繪制的圖一些參數(shù),fig主要是繪制的圖中,軸以外的部分;而axes也就是這個(gè)坐標(biāo)軸的參數(shù)。
subplots是繪制子圖,在這里將它男成2行1列的圖,axes[0]就是第一行,axes[1]就是第二行。
這里我將參數(shù)改一下,就可以稍微理解一些參數(shù)的意義:
圖2.33 更改參數(shù)測(cè)試
從圖2.32可以看出,從20世紀(jì)60年代開始,以字母“n”結(jié)尾的男孩名字出現(xiàn)了顯著的增長?;氐街皠?chuàng)建的那個(gè)完整表,按年度和性別對(duì)其進(jìn)行規(guī)范化處理,并在男孩名字中選取幾個(gè)字母,最后進(jìn)行轉(zhuǎn)置以便將各個(gè)列做成一個(gè)時(shí)間序列:
圖3.34 時(shí)間序列
這里的.T就是轉(zhuǎn)置的意思
繪制趨勢(shì)圖:
圖3.35 各年出生的男孩中名字以d/n/y結(jié)尾的人數(shù)比例
變成女孩名字的男孩名字(以及相反情況)
回到top1000數(shù)據(jù)集,找出其中以“l(fā)esl”開頭的一組名字:
圖2.36 找出以“l(fā)esl”開頭的名字
這里的.unique()是用于求唯一值,感覺用起來和list里面的set有點(diǎn)像。
這里的['lesl' in x.lower() for x in all_namesl] 又是一個(gè)布爾值運(yùn)算數(shù)組,如果看mask的值可以看到:
圖2.38 mask的值
過濾其他的名字,并按名字分組計(jì)算出生數(shù)以查看相對(duì)頻率:
圖2.37?過濾其他的名字,并按名字分組計(jì)算出生數(shù)以查看相對(duì)頻率
pd.isin(values),是否包含數(shù)據(jù)框中的元素
按性別和年度進(jìn)行聚合,并按年度進(jìn)行規(guī)范化處理:
圖2.38
按性別和年度進(jìn)行聚合,并按年度進(jìn)行規(guī)范化處理
這里的.div()我好像之前寫過,不過還是不太熟悉(很尷尬),div主要是用作小數(shù)除法。
繪制年度曲線圖:
圖3.39 各年度使用“Lesley型”名字的男女比例
總結(jié)
以上是生活随笔為你收集整理的python输入一组数据、进行简单的统计_《利用Python进行数据分析》学习笔记——第二章(3)...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 随机组卷python_关于随机自动组卷的
- 下一篇: 云计算实训总结_云计算实习报告.doc