本文中測驗(yàn)需要的文件夾下載鏈接: https://pan.baidu.com/s/1OqFM2TNY75iOST6fBlm6jw 密碼: rmbt
下載壓縮包后解壓如下圖所示:

首先將5題的文件復(fù)制形成副本,如下圖所示:

在資源管理器的路徑中輸入cmd,如下圖所示:

在上圖中輸入后,按Enter鍵運(yùn)行進(jìn)入cmd窗口。
在cmd窗口中輸入并運(yùn)行命令:jupyter notebook,如下圖所示:

在上圖中輸入后,按Enter鍵運(yùn)行自動(dòng)打開瀏覽器并且進(jìn)入jupyter notebook編程界面。
在jupyter notebook中,點(diǎn)擊第一題,ipynb和第一題-副本.ipynb。
瀏覽器會(huì)新建兩個(gè)標(biāo)簽頁,如下圖所示:

在兩個(gè)標(biāo)簽頁中,讀者可以對(duì)照題目要求完成做題。
下面是5道題目作者的答案和解析。
1.第一大題
1.1 第一步:導(dǎo)入相應(yīng)的模塊
最后2行代碼可以使作圖時(shí)不出現(xiàn)編碼錯(cuò)誤,分別用來正常顯示中文標(biāo)簽和正常顯示負(fù)號(hào)。
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用來正常顯示中文標(biāo)簽
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負(fù)號(hào)
1.2 第二步:利用pandas讀取datasets目錄下chipo.csv并顯示前十行數(shù)據(jù)(賦值給變量chipo)
csv文件默認(rèn)的分隔符是逗號(hào),pd.read_csv方法中sep關(guān)鍵字參數(shù)的默認(rèn)值也為逗號(hào),所以可以不寫sep關(guān)鍵字。
顯示前十行數(shù)據(jù)用chipo.head(10)即可。
chipo = pd.read_csv('datasets/chipo.csv')
chipo.head(10)
1.3 第三步:根據(jù)列名為item_name中每種商品出現(xiàn)的頻率,繪制出柱狀圖
給出的答案示例是購買次數(shù)排名第2-6名的商品的作圖結(jié)果。
chipo.item_name.value_counts()是對(duì)商品購買次數(shù)進(jìn)行統(tǒng)計(jì),返回的結(jié)果降序排列,數(shù)據(jù)類型為Series。
plt.xticks()方法中可以填入1個(gè)參數(shù)或者多個(gè)參數(shù),下面代碼中采用的是填入3個(gè)參數(shù)。
x_list是x軸標(biāo)記點(diǎn),數(shù)據(jù)類型為列表;xticks_list是x軸標(biāo)記點(diǎn)顯示值,數(shù)據(jù)類型為列表;
rotation設(shè)置為90,是x軸標(biāo)記點(diǎn)顯示值以右邊為軸逆時(shí)針旋轉(zhuǎn)90度。
plt.bar方法中指定每根柱子的顏色,這樣才可以畫出示例答案的效果。
mostOrder_list = chipo.item_name.value_counts().iloc[5:0:-1]
xticks_list = mostOrder_list.index
x_list = range(len(xticks_list))
y_list = mostOrder_list.values
plt.bar(x_list, y_list, width=0.5, color=['b', 'orange', 'g', 'r', 'purple'])
plt.xticks(x_list, xticks_list, rotation=90)
plt.title('購買次數(shù)最多的商品排名')
plt.xlabel('商品名稱')
plt.ylabel('出現(xiàn)的訂單次數(shù)')
plt.show()
上面這段代碼的運(yùn)行結(jié)果如:

1.4 第四步:根據(jù)訂單編號(hào)(order_id)進(jìn)行分組,求出每個(gè)訂單花費(fèi)的總金額,例如訂單編號(hào)為1的總金額為11.56美元。然后根據(jù)每筆訂單的總金額和每筆訂單購買商品的總數(shù)量畫出散點(diǎn)圖(總金額為x軸,商品總數(shù)為y軸)。
先將chipo這個(gè)變量深度拷貝給c變量,這樣可以避免影響原數(shù)據(jù),使代碼每次都能成功運(yùn)行。
item_price這個(gè)單詞是一個(gè)條目的價(jià)格,不是單個(gè)商品的單價(jià)。
我們平時(shí)超市購物的單子的最后price那一列也是算的這一個(gè)條目的價(jià)格,比如2個(gè)相同的商品算1個(gè)條目。
c = chipo.copy()
c.quantity = c.quantity.astype('int')
c.item_price = c.item_price.str.strip('$').astype('float')
order_group = c.groupby('order_id')
x_list = order_group.item_price.sum()
y_list = order_group.quantity.sum()
plt.scatter(x_list, y_list, color='g')
plt.xlabel('訂單總價(jià)')
plt.ylabel('商品總數(shù)')
plt.title('每筆訂單總金融和購買商品數(shù)量關(guān)系')
plt.show()
上面這段代碼的運(yùn)行結(jié)果如下:

2.第二大題
2.1 第一步:導(dǎo)入相應(yīng)的模塊
最后2行代碼可以使作圖時(shí)不出現(xiàn)編碼錯(cuò)誤,分別用來正常顯示中文標(biāo)簽和正常顯示負(fù)號(hào)。
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用來正常顯示中文標(biāo)簽
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負(fù)號(hào)
2.2 第二步:利用pandas讀取datasets目錄下special_top250.csv并顯示前五行數(shù)據(jù)(賦值給變量top250)
csv文件默認(rèn)的分隔符是逗號(hào),pd.read_csv方法中sep關(guān)鍵字參數(shù)的默認(rèn)值也為逗號(hào),所以可以不寫sep關(guān)鍵字。
顯示前五行數(shù)據(jù)用chipo.head()即可。
top250 = pd.read_csv('datasets/special_top250.csv')
top250.head()
2.3 第三步:在同一個(gè)圖中繪制出電影時(shí)長和電影排名的散點(diǎn)圖關(guān)系及電影時(shí)長的頻率分布直方圖,分50組,如下圖所示:
x_series = top250.movie_duration
y_series = top250.num
plt.figure(figsize=(14,6))
plt.subplot(121)
plt.scatter(x_series, y_series)
plt.xlabel('電影時(shí)長')
plt.ylabel('電影排名')
plt.gca().invert_yaxis()
plt.subplot(122)
plt.hist(x_series,bins=50)
plt.show()
上面一段代碼的運(yùn)行結(jié)果如下:

2.4 第四步:由上圖中電影時(shí)長的頻率分布直方圖,并不能比較準(zhǔn)確的反映出每個(gè)分組下電影的數(shù)量,請(qǐng)根據(jù)以下提示,繪制如下圖所示根據(jù)電影時(shí)長分組的柱狀圖
bins = [0,80,120,140,180,1000]
tags = ['偏短','標(biāo)準(zhǔn)','正常','偏長','超長']
2.5 第五步:具體顯示每個(gè)分組下的電影數(shù)量
在pandas官網(wǎng)中查詢pandas.cut函數(shù)中的參數(shù),其中參數(shù)bins是數(shù)據(jù)區(qū)間分割值,參數(shù)labels是數(shù)據(jù)按照區(qū)間分類后的標(biāo)簽,如下圖所示。如果參數(shù)bins和labels都是可迭代對(duì)象,則bins比labels長度大1。

將電影時(shí)長分類后賦值給duration_labeled_series變量,數(shù)據(jù)類型為Series。查看其中的值,如下圖所示:

對(duì)duration_labeled_series變量統(tǒng)計(jì)每個(gè)分類出現(xiàn)的次數(shù),使用value_counts方法。
duration_series = top250.movie_duration
duration_labeled_series = pd.cut(duration_series, bins=bins, labels=tags)
duration_labeled_series.value_counts()
2.6 第六步:繪制出結(jié)果圖
duration_stat_series = duration_labeled_series.value_counts(sort=False)
duration_stat_series.plot(kind='bar')
plt.show()
上面一段代碼的運(yùn)行結(jié)果如下:

3.第三大題
3.1 第一步:導(dǎo)入相關(guān)模塊
最后2行代碼可以使作圖時(shí)不出現(xiàn)編碼錯(cuò)誤,分別用來正常顯示中文標(biāo)簽和正常顯示負(fù)號(hào)。
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用來正常顯示中文標(biāo)簽
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負(fù)號(hào)
3.2 第二步:加載datasets下的tips.csv文件數(shù)據(jù),并顯示前五行記錄
csv文件默認(rèn)的分隔符是逗號(hào),pd.read_csv方法中sep關(guān)鍵字參數(shù)的默認(rèn)值也為逗號(hào),所以可以不寫sep關(guān)鍵字。
顯示前五行數(shù)據(jù)用chipo.head()即可。
tip_df = pd.read_csv('datasets/tips.csv')
tip_df.head()
3.3 第三步:繪制消費(fèi)金額頻率分布直方圖
plt.hist方法中參數(shù)bins用來指定出現(xiàn)多少根柱子,參數(shù)width用來指定每根柱子的寬度。
plt.hist(tip_df.total_bill, bins=10, width=4)
plt.xlabel('消費(fèi)總金額')
plt.ylabel('頻率')
plt.show()
上面一段代碼的運(yùn)行結(jié)果如下圖所示:

3.4 第四步:繪制總消費(fèi)金額與小費(fèi)金額的散點(diǎn)圖關(guān)系
利用plt.scatter方法畫出散點(diǎn)圖
plt.scatter(tip_df.total_bill, tip_df.tip)
plt.xlabel('總消費(fèi)金額')
plt.ylabel('小費(fèi)金額')
plt.show()
上面一段代碼的運(yùn)行結(jié)果如下:

3.5 第五步:在同一圖中繪制出吸煙顧客與不吸煙顧客的消費(fèi)金額與小費(fèi)之間的散點(diǎn)圖關(guān)系
觀察示例答案中左右兩幅圖,不同的地方有:處于畫板的位置、標(biāo)題、散點(diǎn)顏色。
定義函數(shù)drawScatter用于繪制散點(diǎn)圖,傳入4個(gè)參數(shù):數(shù)據(jù)group、處于畫板的位置subplot、標(biāo)題title、散點(diǎn)顏色。
def drawScatter(group, subplot, title, color):
plt.subplot(subplot)
plt.xlabel('消費(fèi)總金額')
plt.ylabel('小費(fèi)金額')
plt.title(title)
plt.scatter(group.total_bill, group.tip, color=color)
plt.figure(figsize=(12,6))
for name,group in tip_df.groupby('smoker'):
if name == 'Yes':
drawScatter(group, 121, '吸煙顧客', 'green')
else:
drawScatter(group, 122, '不吸煙顧客', 'blue')
plt.show()
上面一段代碼的運(yùn)行結(jié)果如下:

3.6 第六步:在同一圖中繪制出女性與男性中吸煙與不吸煙顧客的消費(fèi)金額與小費(fèi)之間的散點(diǎn)圖關(guān)系
在有2組散點(diǎn)的散點(diǎn)圖當(dāng)中,第1組散點(diǎn)默認(rèn)為橘黃色,第2組散點(diǎn)默認(rèn)為天藍(lán)色。
def drawScatter2(df, subplot, title, sex):
plt.subplot(subplot)
plt.title(title)
for name, group in df.groupby('smoker'):
if name == 'Yes':
plt.scatter(group.total_bill, group.tip,
label=sex+'吸煙顧客')
else:
plt.scatter(group.total_bill, group.tip,
label=sex+'不吸煙顧客')
plt.legend()
plt.figure(figsize=(12,6))
for name,group in tip_df.groupby('sex'):
if name == 'Male':
drawScatter2(group, 121, 'sex=Male', '男性')
else:
drawScatter2(group, 122, 'sex=Female', '女性')
plt.show()
上面一段代碼的運(yùn)行結(jié)果如下圖所示:

4.第四大題
4.1 第一步:導(dǎo)入相應(yīng)的模塊
import os
import re
import numpy as np
import pandas as pd
from bs4 import BeautifulSoup
4.2 第二步:讀取nlp文件夾下的labeledTraniData.tsv文件
df = pd.read_csv("nlp/labeledTrainData.tsv", sep='\t', escapechar='\\')
print('記錄數(shù): {}'.format(len(df)))
df.head()
4.3 第三步:請(qǐng)按如下步驟,對(duì)影評(píng)數(shù)據(jù)做預(yù)處理,大概有以下環(huán)節(jié):
- 去掉html標(biāo)簽
- 移除標(biāo)點(diǎn)
- 切分成單詞列表
- 去掉停用詞
- 重組為新的句子
def display(text, title):
print(title)
print("\n----------我是分割線-------------\n")
print(text)
4.4 第四步:提取出原始數(shù)據(jù)中的第一行review列中的文本數(shù)據(jù),并用display函數(shù)進(jìn)行輸出顯示
text1 = df.iloc[1]['review']
display(text1, '原始數(shù)據(jù)')
4.5 第五步:用BeautifulSoup將第四步中獲取到的數(shù)據(jù)中的html標(biāo)簽去除
text2 = BeautifulSoup(text1, 'lxml').text
display(text2, '去掉HTML標(biāo)簽的數(shù)據(jù)')
4.6 第六步:將第五步數(shù)據(jù)中的標(biāo)點(diǎn)符號(hào)去掉(用正則)
text3 = re.sub('[^\w\s]', '',text2)
display(text3, '去掉標(biāo)點(diǎn)的數(shù)據(jù)')
4.7 第七步:將第六步的數(shù)據(jù)全部轉(zhuǎn)換成小寫并轉(zhuǎn)換成列表
text4 = text3.lower()
word_list = text4.split(' ')
display(word_list, '純?cè)~列表數(shù)據(jù)')
4.8 第八步:去掉第七步數(shù)據(jù)中的英文停用詞
4.8.1 加載英文停用詞
with open('nlp/stopwords.txt') as file:
stopword_list = [k.strip() for k in file.readlines()]
4.8.2 利用加載的英文停用詞,去除第七部數(shù)據(jù)中的英文停用詞
new_word_list = [k for k in word_list if k not in stopword_list]
display(new_word_list, '去掉停用詞數(shù)據(jù)')
4.8.3 為確保所加載的英文停用詞沒有重復(fù)數(shù)據(jù),請(qǐng)對(duì)8-1中加載的英文停用詞去重
stopword_list = list(set(stopword_list))
4.9 第九步:將第五步到第八步的過程總結(jié)歸納為一個(gè)函數(shù),名為clean_text,參數(shù)為text即輸入到函數(shù)中的文本
這個(gè)函數(shù)就是對(duì)前面零散步驟的總結(jié),所以前面的大部分代碼可以直接復(fù)制過來。
with open('nlp/stopwords.txt') as file:
stopword_list = [k.strip() for k in file.readlines()]
stopword_list = list(set(stopword_list))
def clean_text(text1):
text2 = BeautifulSoup(text1, 'lxml').text
text3 = re.sub('[^\w\s]', '',text2)
text4 = text3.lower()
word_list = text4.split(' ')
new_word_list = [k for k in word_list if k not in stopword_list]
return ' '.join(new_word_list)
4.10 第十步:用apply方法,將第九步中定義的函數(shù)應(yīng)用到第二步加載的df中,并生成一列清洗之后的數(shù)據(jù)列,名為clean_review
df['clean_review'] = df.review.apply(clean_text)
df.head()
上面一段代碼的運(yùn)行結(jié)果如下圖所示:

5.第五大題
5.1 第一步:導(dǎo)入相關(guān)模塊
最后2行代碼可以使作圖時(shí)不出現(xiàn)編碼錯(cuò)誤,分別用來正常顯示中文標(biāo)簽和正常顯示負(fù)號(hào)。
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用來正常顯示中文標(biāo)簽
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負(fù)號(hào)
5.2 第二步:加載datasets目錄下US_Baby_names_right.csv文件數(shù)據(jù)并查看數(shù)據(jù)的基本信息
baby_df = pd.read_csv('datasets/US_Baby_names_right.csv')
baby_df.info()
5.3 第三步:寫出刪除 Unname:0和Id列數(shù)據(jù)的兩種方法,第二種注釋即可
new_df = baby_df.drop(['Unnamed: 0', 'Id'], axis=1)
# del baby_df['Unnamed: 0']
# del baby_df['Id']
new_df.head()
5.4 第四步:寫出能夠判斷出數(shù)據(jù)集中男孩多還是女孩多的代碼并給出結(jié)論
baby_df.Gender.value_counts()
5.5 第五步:按照Name字段將數(shù)據(jù)集進(jìn)行分組并求和賦值給變量names,最后輸出前五行
names = new_df.groupby('Name').sum()
names.head()
5.6 第六步:按照每個(gè)名字被使用的次數(shù)(Count)對(duì)第五步中結(jié)果進(jìn)行降序排序,得出最受歡迎的的五個(gè)名字
sorted_names = names.sort_values(by='Count', ascending=False)
sorted_names.head()
5.7 第七步:在數(shù)據(jù)集中,共出現(xiàn)了多少個(gè)名字?(不包含重復(fù)項(xiàng),至少使用兩種方法)
第1種方法:
len(baby_df.Name.unique())
第2種方法:
len(names)
第3種方法:
baby_df.Name.value_counts().count()
5.8 第八步:出現(xiàn)次數(shù)最少的名字共有幾個(gè)?
min_count = sorted_names.iloc[-1]['Count']
len(names[names.Count == min_count])
5.9 第九步:根據(jù)names變量中的數(shù)據(jù),刪除掉Year列數(shù)據(jù)后,得出如下所示的基本統(tǒng)計(jì)參數(shù)
names.drop('Year', axis=1).describe()