1. 缺失值處理
本文所使用到的所有數據在此處下載:
鏈接:https://pan.baidu.com/s/16ayvfRw95K0xma9o3YPN3Q 密碼:qgt3
判斷缺失值是否存在,示例代碼如下:
import numpy as np
import pandas as pd
type(np.NAN) # float
# 讀取電影數據
movie_data = pd.read_csv("./data/IMDB-Movie-Data.csv")
# 1.判斷是否存在缺失值
np.any(pd.isnull(movie_data)) # 裏面如果有一個缺失值,就返回True
# 2.判斷缺失值是否存在
np.all(pd.notnull(movie_data)) # 裏面如果有一個缺失值,就返回False
處理缺失值,示例代碼如下:
# 處理缺失值
# 1.刪除缺失值 pandas刪除缺失值,使用dropna的前提是,缺失值的類型必須是np.nan
movie_data.dropna() # 不修改原數據
np.any(pd.isnull(movie_data)) # True
data = movie_data.dropna() # 可以使用一個新的變量接收它
np.any(pd.isnull(data)) # False
# 2.替換缺失值
# 不修改原有的數據 用平均值來進行代替
data2 = movie_data["Revenue (Millions)"].fillna(value=movie_data["Revenue (Millions)"].mean())
# 直接將原有的數據進行修改
# movie_data["Revenue (Millions)"].fillna(value=movie_data["Revenue (Millions)"].mean(), inplace=True)
data2
# 3.替換所有缺失值
for i in movie_data.columns:
# print(i)
if np.all(pd.notnull(movie_data[i])) == False:
# print(i)
# 替換
movie_data[i].fillna(value=movie_data[i].mean(), inplace=True)
np.any(pd.isnull(data))
不是缺失值 nan
的,而是有 ?
等默認標記的處理,示例代碼如下:
# 有默認標記的處理
# 數據準備
wis = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data")
# 1.先替換"?"爲np.nan to_replace: 替換前的值 value: 替換後的值
wis = wis.replace(to_replace="?", value=np.nan)
# 2.在進行缺失值的處理
wis.dropna()
2. 數據離散化
2.1 爲什麼要離散化?
連續屬性離散化的目的是爲了簡化數據結構,數據離散化技術可以用來減少給定連續屬性值的個數。離散化方法經常作爲數據挖掘的工具。
2.2 什麼是數據的離散化?
連續屬性的離散化就是在連續屬性的值域上,將值域劃分爲若干個離散的區間,最後用不同的符號或整數 值代表落在每個子區間中的屬性值。離散化有很多種方法,這裏使用一種最簡單的方式去操作,如下:
- 原始人的身高數據:165,174,160,180,159,163,192,184
- 假設按照身高分幾個區間段:150~165, 165~180,180~195
接下來對股票每日的 p_change
進行離散化,示例代碼如下:
# 1.讀取文件
data = pd.read_csv("./data/stock_day.csv")
# 2.刪除一些列,讓數據更簡單些,再去做後面的操作
data = data.drop(["ma5","ma10","ma20","v_ma5","v_ma10","v_ma20"], axis=1)
p_change = data["p_change"]
# p_change
# 3. 對數據進行分組將數據分組 一般會與value_counts搭配使用,統計每組的個數
qcut = pd.qcut(p_change, 10) # 自由分組 組數爲10
qcut.value_counts() # 統計每組的個數
上述代碼執行結果如下:
當然,我們也可以自定義區間分組,示例代碼如下:
# 自己指定分組區間
bins = [-100, -7, -5, -3, 0, 3, 5, 7, 100]
p_counts = pd.cut(p_change, bins)
p_counts
結果如下:
2.3 股票漲跌幅分組數據變成one-hot編碼
把每個類別生成一個布爾列,這些列中只有一列可以爲這個樣本取值爲1。其又被稱爲熱編碼。把下圖中左邊的表格轉化爲使用右邊形式進行表示:
示例代碼如下:
# 得出one-hot編碼矩陣
dummies = pd.get_dummies(p_counts, prefix="rise")
dummies.head() # 只取了前5行演示結果
結果如下:
3. 合併
如果你的數據由多張表組成,那麼有時候需要將不同的內容合併在一起分析。
pd.concat([data1, data2], axis=1) 按照行或列進行合併,axis=0爲列索引,axis=1爲行索引,示例代碼如下:
dict1 = {"name": ["amo","jerry","paul","jason"], "age": [18,30,21,25]}
data1 = pd.DataFrame(dict1)
data2 = pd.DataFrame({"adress":["上海","山東","重慶","四川"], "hobby": ["唱歌","看小說","撩妹","旅遊"]})
# 將data1表和data2表合併
pd.concat([data1, data2], axis=1) # 指定軸
結果如下所示:
指定按照兩組數據的共同鍵值對合並或者左右各自,語法格式如下:
pd.merge(left, right, how='inner', on=None,
left_on=None, right_on=None)
參數說明如下:
- left:A DataFrame object
- right:Another DataFrame object
- on:Columns (names) to join on. Must be found in both the left and right DataFrame objects.
- left_on=None, right_on=None:指定左右鍵
Merge method | SQL Join Name | Description |
---|---|---|
left | LEFT OUTER JOIN | Use keys from left frame only |
right | RIGHT OUTER JOIN | Use keys from right frame only |
outer | FULL OUTER JOIN | Use union of keys from both frames |
inner | INNER JOIN | Use intersection of keys from both frames |
示例代碼如下:
left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
'key2': ['K0', 'K1', 'K0', 'K1'],
'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
'key2': ['K0', 'K0', 'K0', 'K0'],
'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3']})
# 默認內連接
result = pd.merge(left, right, on=['key1', 'key2'])
result # 有點類似於數據庫
結果如下所示:
左連接,示例代碼如下:
# 左連接
result = pd.merge(left, right, how='left', on=['key1', 'key2'])
result
結果如下所示:
右連接,示例代碼如下:
result = pd.merge(left, right, how='right', on=['key1', 'key2'])
result
結果如下所示:
外連接,示例代碼如下:
result = pd.merge(left, right, how='outer', on=['key1', 'key2'])
result
結果如下所示:
4. 交叉表與透視表
交叉表用於計算一列數據對於另外一列數據的分組個數(尋找兩個列之間的關係)。用以下案例進行具體說明,示例代碼如下:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 準備兩列數據,星期數據以及漲跌幅是好是壞數據
stock_data = pd.read_csv("./data/stock_day.csv")
stock_data
# 尋找星期幾跟股票張得的關係
# 1.先把對應的日期找到星期幾
date = pd.to_datetime(stock_data.index).weekday
stock_data["week"] = date
# stock_data
# 2.假如把p_change按照大小去分個類0爲界限
stock_data['posi_neg'] = np.where(stock_data["p_change"]>0, 1, 0)
# stock_data.head(20)
# 3.查找兩列的關係
count = pd.crosstab(stock_data["week"], stock_data["posi_neg"])
# count
# 4.計算百分比
sum1 = count.sum(axis=1) # 默認按列進行求和 需要指定軸
pro = count.div(sum1, axis=0) # 需要指定軸 注意軸不用死記 用的時候試試就好了
# 5.展示數據
pro.plot(kind="bar", stacked=True) # 可以發現比matplotlib畫圖更簡單
plt.show()
# 通過透視表,將整個過程變成更簡單一些
stock_data.pivot_table(['posi_neg'], index='week')
結果如下所示:
5. 分組與聚合
分組與聚合通常是分析數據的一種方式,通常與一些統計函數一起使用,查看數據的分組情況。想一想上面的交叉表與透視表也有分組的功能,所以算是分組的一種形式,只不過他們主要是計算次數或者計算比例。效果:
API:DataFrame.groupby(key, as_index=False),用一個案例來進行說明,不同顏色的不同筆的價格數據,示例代碼如下:
col = pd.DataFrame({'color': ['white','red','green','red','green'],
'object': ['pen','pencil','pencil','ashtray','pen'],
'price1':[5.56,4.20,1.30,0.56,2.75],
'price2':[4.75,4.12,1.60,0.75,3.15]})
# 1.進行分組,對顏色分組,price進行聚合求平均值
col.groupby(by="color")["price1"].mean()
# 這樣寫也是可以的 我習慣上面一種
col["price1"].groupby(by=col["color"]).mean() # 這種方式不能使用as_index:設置索引
col.groupby(by="color", as_index=False)["price1"].mean()
現在我們有一組關於全球星巴克店鋪的統計數據,如果我想知道美國的星巴克數量和中國的哪個多,或者我想知道中國每個省份星巴克的數量的情況,那麼應該怎麼辦?示例代碼如下:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 1.從文件中讀取辛巴克數據
starbucks = pd.read_csv("./data/starbucks/directory.csv")
# 2.按照國家分組,求出每個國家的星巴克零售店數量
count = starbucks.groupby(["Country"]).count()
# 3.全部展示出來太亂 先排序 然後取前20的數據展示即可
# ascending=False 降序排列
count["Brand"].sort_values(ascending=False)[:20].plot(kind="bar", figsize=(20, 8))
plt.show()
上述代碼執行結果如下:
假設我們加入省市一起進行分組,示例代碼如下:
starbucks.groupby(["Country","State/Province"]).count()
結果如下圖所示: