本文中測驗需要的檔案夾下載下傳連結: https://pan.baidu.com/s/1OqFM2TNY75iOST6fBlm6jw
密碼: rmbt
下載下傳壓縮包後解壓如下圖所示:
image.png
首先将5題的檔案複制形成副本,如下圖所示:
在資料總管的路徑中輸入cmd,如下圖所示:在上圖中輸入後,按Enter鍵運作進入cmd視窗。
在cmd視窗中輸入并運作指令:jupyter notebook,如下圖所示:
在上圖中輸入後,按Enter鍵運作自動打開浏覽器并且進入jupyter notebook程式設計界面。
在jupyter notebook中,點選第一題,ipynb和第一題-副本.ipynb。
浏覽器會建立兩個标簽頁,如下圖所示:
在兩個标簽頁中,讀者可以對照題目要求完成做題。
下面是5道題目作者的答案和解析。
1.第一大題
1.1 第一步:導入相應的子產品
最後2行代碼可以使作圖時不出現編碼錯誤,分别用來正常顯示中文标簽和正常顯示負号。
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用來正常顯示中文标簽
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負号
1.2 第二步:利用pandas讀取datasets目錄下chipo.csv并顯示前十行資料(指派給變量chipo)
csv檔案預設的分隔符是逗号,pd.read_csv方法中sep關鍵字參數的預設值也為逗号,是以可以不寫sep關鍵字。
顯示前十行資料用chipo.head(10)即可。
chipo = pd.read_csv('datasets/chipo.csv')
chipo.head(10)
1.3 第三步:根據列名為item_name中每種商品出現的頻率,繪制出柱狀圖
給出的答案示例是購買次數排名第2-6名的商品的作圖結果。
chipo.item_name.value_counts()是對商品購買次數進行統計,傳回的結果降序排列,資料類型為Series。
plt.xticks()方法中可以填入1個參數或者多個參數,下面代碼中采用的是填入3個參數。
x_list是x軸标記點,資料類型為清單;xticks_list是x軸标記點顯示值,資料類型為清單;
rotation設定為90,是x軸标記點顯示值以右邊為軸逆時針旋轉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('購買次數最多的商品排名')
plt.xlabel('商品名稱')
plt.ylabel('出現的訂單次數')
plt.show()
上面這段代碼的運作結果如:
柱形圖.png
1.4 第四步:根據訂單編号(order_id)進行分組,求出每個訂單花費的總金額,例如訂單編号為1的總金額為11.56美元。然後根據每筆訂單的總金額和每筆訂單購買商品的總數量畫出散點圖(總金額為x軸,商品總數為y軸)。
先将chipo這個變量深度拷貝給c變量,這樣可以避免影響原資料,使代碼每次都能成功運作。
item_price這個單詞是一個條目的價格,不是單個商品的單價。
我們平時超市購物的單子的最後price那一列也是算的這一個條目的價格,比如2個相同的商品算1個條目。
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('訂單總價')
plt.ylabel('商品總數')
plt.title('每筆訂單總金融和購買商品數量關系')
plt.show()
上面這段代碼的運作結果如下:
散點圖.png
2.第二大題
2.1 第一步:導入相應的子產品
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用來正常顯示中文标簽
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負号
2.2 第二步:利用pandas讀取datasets目錄下special_top250.csv并顯示前五行資料(指派給變量top250)
顯示前五行資料用chipo.head()即可。
top250 = pd.read_csv('datasets/special_top250.csv')
top250.head()
2.3 第三步:在同一個圖中繪制出電影時長和電影排名的散點圖關系及電影時長的頻率分布直方圖,分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('電影時長')
plt.ylabel('電影排名')
plt.gca().invert_yaxis()
plt.subplot(122)
plt.hist(x_series,bins=50)
plt.show()
上面一段代碼的運作結果如下:
2.4 第四步:由上圖中電影時長的頻率分布直方圖,并不能比較準确的反映出每個分組下電影的數量,請根據以下提示,繪制如下圖所示根據電影時長分組的柱狀圖
bins = [0,80,120,140,180,1000]
tags = ['偏短','标準','正常','偏長','超長']
2.5 第五步:具體顯示每個分組下的電影數量
在pandas官網中查詢pandas.cut函數中的參數,其中參數bins是資料區間分割值,參數labels是資料按照區間分類後的标簽,如下圖所示。如果參數bins和labels都是可疊代對象,則bins比labels長度大1。
pandas.cut用法官方文檔.png
将電影時長分類後指派給duration_labeled_series變量,資料類型為Series。檢視其中的值,如下圖所示:
對duration_labeled_series變量統計每個分類出現的次數,使用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 第六步:繪制出結果圖
duration_stat_series = duration_labeled_series.value_counts(sort=False)
duration_stat_series.plot(kind='bar')
plt.show()
3.第三大題
3.1 第一步:導入相關子產品
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用來正常顯示中文标簽
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負号
3.2 第二步:加載datasets下的tips.csv檔案資料,并顯示前五行記錄
tip_df = pd.read_csv('datasets/tips.csv')
tip_df.head()
3.3 第三步:繪制消費金額頻率分布直方圖
plt.hist方法中參數bins用來指定出現多少根柱子,參數width用來指定每根柱子的寬度。
plt.hist(tip_df.total_bill, bins=10, width=4)
plt.xlabel('消費總金額')
plt.ylabel('頻率')
plt.show()
上面一段代碼的運作結果如下圖所示:
直方圖.png
3.4 第四步:繪制總消費金額與小費金額的散點圖關系
利用plt.scatter方法畫出散點圖
plt.scatter(tip_df.total_bill, tip_df.tip)
plt.xlabel('總消費金額')
plt.ylabel('小費金額')
plt.show()
3.5 第五步:在同一圖中繪制出吸煙顧客與不吸煙顧客的消費金額與小費之間的散點圖關系
觀察示例答案中左右兩幅圖,不同的地方有:處于畫闆的位置、标題、散點顔色。
定義函數drawScatter用于繪制散點圖,傳入4個參數:資料group、處于畫闆的位置subplot、标題title、散點顔色。
def drawScatter(group, subplot, title, color):
plt.subplot(subplot)
plt.xlabel('消費總金額')
plt.ylabel('小費金額')
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()
組合散點圖.png
3.6 第六步:在同一圖中繪制出女性與男性中吸煙與不吸煙顧客的消費金額與小費之間的散點圖關系
在有2組散點的散點圖當中,第1組散點預設為橘黃色,第2組散點預設為天藍色。
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()
4.第四大題
4.1 第一步:導入相應的子產品
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('記錄數: {}'.format(len(df)))
df.head()
4.3 第三步:請按如下步驟,對影評資料做預處理,大概有以下環節:
- 去掉html标簽
- 移除标點
- 切分成單詞清單
- 去掉停用詞
- 重組為新的句子
def display(text, title):
print(title)
print("\n----------我是分割線-------------\n")
print(text)
4.4 第四步:提取出原始資料中的第一行review列中的文本資料,并用display函數進行輸出顯示
text1 = df.iloc[1]['review']
display(text1, '原始資料')
4.5 第五步:用BeautifulSoup将第四步中擷取到的資料中的html标簽去除
text2 = BeautifulSoup(text1, 'lxml').text
display(text2, '去掉HTML标簽的資料')
4.6 第六步:将第五步資料中的标點符号去掉(用正則)
text3 = re.sub('[^\w\s]', '',text2)
display(text3, '去掉标點的資料')
4.7 第七步:将第六步的資料全部轉換成小寫并轉換成清單
text4 = text3.lower()
word_list = text4.split(' ')
display(word_list, '純詞清單資料')
4.8 第八步:去掉第七步資料中的英文停用詞
4.8.1 加載英文停用詞
with open('nlp/stopwords.txt') as file:
stopword_list = [k.strip() for k in file.readlines()]
4.8.2 利用加載的英文停用詞,去除第七部資料中的英文停用詞
new_word_list = [k for k in word_list if k not in stopword_list]
display(new_word_list, '去掉停用詞資料')
4.8.3 為確定所加載的英文停用詞沒有重複資料,請對8-1中加載的英文停用詞去重
stopword_list = list(set(stopword_list))
4.9 第九步:将第五步到第八步的過程總結歸納為一個函數,名為clean_text,參數為text即輸入到函數中的文本
這個函數就是對前面零散步驟的總結,是以前面的大部分代碼可以直接複制過來。
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方法,将第九步中定義的函數應用到第二步加載的df中,并生成一列清洗之後的資料列,名為clean_review
df['clean_review'] = df.review.apply(clean_text)
df.head()
第4題最終結果.png
5.第五大題
5.1 第一步:導入相關子產品
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用來正常顯示中文标簽
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負号
5.2 第二步:加載datasets目錄下US_Baby_names_right.csv檔案資料并檢視資料的基本資訊
baby_df = pd.read_csv('datasets/US_Baby_names_right.csv')
baby_df.info()
5.3 第三步:寫出删除 Unname:0和Id列資料的兩種方法,第二種注釋即可
new_df = baby_df.drop(['Unnamed: 0', 'Id'], axis=1)
# del baby_df['Unnamed: 0']
# del baby_df['Id']
new_df.head()
5.4 第四步:寫出能夠判斷出資料集中男孩多還是女孩多的代碼并給出結論
baby_df.Gender.value_counts()
5.5 第五步:按照Name字段将資料集進行分組并求和指派給變量names,最後輸出前五行
names = new_df.groupby('Name').sum()
names.head()
5.6 第六步:按照每個名字被使用的次數(Count)對第五步中結果進行降序排序,得出最受歡迎的的五個名字
sorted_names = names.sort_values(by='Count', ascending=False)
sorted_names.head()
5.7 第七步:在資料集中,共出現了多少個名字?(不包含重複項,至少使用兩種方法)
第1種方法:
len(baby_df.Name.unique())
第2種方法:
len(names)
第3種方法:
baby_df.Name.value_counts().count()
5.8 第八步:出現次數最少的名字共有幾個?
min_count = sorted_names.iloc[-1]['Count']
len(names[names.Count == min_count])
5.9 第九步:根據names變量中的資料,删除掉Year列資料後,得出如下所示的基本統計參數
names.drop('Year', axis=1).describe()