4.1-4.3 數據預處理-清洗-變換-離散化

整個第四章都是數據預處理。

4.1是數據清洗。就是處理無關數據,缺失或者異常數據等等。

具體看書,就不贅述了,還是上代碼實踐。

書上給的代碼是有問題的!

#拉格朗日插值代碼
import pandas as pd #導入數據分析庫Pandas
from scipy.interpolate import lagrange #導入拉格朗日插值函數

inputfile = 'data/catering_sale.xls' #銷量數據路徑
outputfile = 'tmp/sales.xls' #輸出數據路徑

data = pd.read_excel(inputfile) #讀入數據
data[u'銷量'][(data[u'銷量'] < 400) | (data[u'銷量'] > 5000)] = None #過濾異常值,將其變爲空值

#自定義列向量插值函數
#s爲列向量,n爲被插值的位置,k爲取前後的數據個數,默認爲5
def ployinterp_column(s, n, k=5):
  y = s[list(range(n-k, n)) + list(range(n+1, n+1+k))] #取數
  y = y[y.notnull()] #剔除空值
  return lagrange(y.index, list(y))(n) #插值並返回拉格朗日插值結果

#逐個元素判斷是否需要插值
for i in data.columns:
  for j in range(len(data)):
    if (data[i].isnull())[j]: #如果爲空即插值。
      data[i][j] = ployinterp_column(data[i], j)

data.to_excel(outputfile) #輸出結果,寫入文件

究其原因,應該是

data[u'銷量'][(data[u'銷量'] < 400) | (data[u'銷量'] > 5000)] = None #過濾異常值,將其變爲空值
這句話有問題。

改正方法主要是 .loc 函數進行修改。

.loc 函數主要是選定指定列操作,參見 http://blog.csdn.net/chixujohnny/article/details/51095817


參考下面這個鏈接

http://blog.csdn.net/o1101574955/article/details/51627401

給出了修改版:

# -*- coding:utf-8 -*-
#拉格朗日插值代碼
import pandas as pd #導入數據分析庫Pandas
from scipy.interpolate import lagrange #導入拉格朗日插值函數

inputfile = 'data/catering_sale.xls' #銷量數據路徑
outputfile = 'tmp/sales.xls' #輸出數據路徑

data = pd.read_excel(inputfile) #讀入數據
#data[u'銷量'][(data[u'銷量'] < 400) | (data[u'銷量'] > 5000)] = None #過濾異常值,將其變爲空值
row_indexs = (data[u'銷量'] < 400) | (data[u'銷量'] > 5000)  #得到過濾數據的索引
data.loc[row_indexs,u'銷量'] = None  #過濾數據

#自定義列向量插值函數
#s爲列向量,n爲被插值的位置,k爲取前後的數據個數,默認爲5
def ployinterp_column(s, n, k=5):
    y = s[list(range(n-k, n)) + list(range(n+1, n+1+k))] #取數
    y = y[y.notnull()] #剔除空值
    return lagrange(y.index, list(y))(n) #插值並返回拉格朗日插值結果

#逐個元素判斷是否需要插值
for i in data.columns:
    for j in range(len(data)):
        if (data[i].isnull())[j]: #如果爲空即插值。
#       data[i][j] = ployinterp_column(data[i], j)
            data.loc[j,i] = ployinterp_column(data[i], j)
data.to_excel(outputfile) #輸出結果,寫入文件



這時候我在 http://blog.csdn.net/aq_cainiao_aq/article/details/53257136 也看見一篇,我沒試過,可以參考。


def那段代碼應該要結合拉格朗日插值法具體看,現在簡單分析一下:

s爲列向量,n爲被插值的位置,k爲取前後的數據個數,默認爲5。

返回的拉格朗日函數有兩個值,y.index應該是插值位置,list(y) 就是結果吧。

可惜沒找到關於 lagrange 函數的說明,只能猜。 


現在的問題是,日期全變成了 ######,想想怎麼修改呢?

其實日期是沒問題的,但是後面多了時分秒,太長了就變成了######。我不想要這個東西。

去百度搜索了很久,http://blog.csdn.net/dm_vincent/article/details/48696857 參考了一下這個,但是感覺沒看懂。


不過呢,插值算是處理好了。

===================================================================================================

4.3講的是數據變換


主要是數據的規範化處理,把數據轉換成“適當的”形式。

代碼就是狗屎,我自己補充了一下,給的代碼不僅沒有 print ,還tm少了一個 import,真的服了

#-*- coding: utf-8 -*-
#數據規範化
import pandas as pd
import numpy as np

datafile = 'data/normalization_data.xls' #參數初始化
data = pd.read_excel(datafile, header = None) #讀取數據

print (data - data.min())/(data.max() - data.min()) #最小-最大規範化
print (data - data.mean())/data.std() #零-均值規範化
print data/10**np.ceil(np.log10(data.abs().max())) #小數定標規範化


就是如此。

==================================================================================================


4.3.3講的是連續屬性離散化。                                                                                                                                                                                         但是這代碼都是什麼鬼???

#-*- coding: utf-8 -*-
#數據規範化
import pandas as pd

datafile = 'data/discretization_data.xls' #參數初始化
data = pd.read_excel(datafile) #讀取數據
data = data[u'肝氣鬱結證型係數'].copy()
k = 4

d1 = pd.cut(data, k, labels = range(k)) #等寬離散化,各個類比依次命名爲0,1,2,3
# http://pandas.pydata.org/pandas-docs/stable/generated/pandas.cut.html pd.cut

#等頻率離散化
w = [1.0*i/k for i in range(k+1)]
w = data.describe(percentiles = w)[4:4+k+1] #使用describe函數自動計算分位數
w[0] = w[0]*(1-1e-10)
d2 = pd.cut(data, w, labels = range(k))

from sklearn.cluster import KMeans #引入KMeans
kmodel = KMeans(n_clusters = k, n_jobs = 4) #建立模型,n_jobs是並行數,一般等於CPU數較好
kmodel.fit(data.reshape((len(data), 1))) #訓練模型
c = pd.DataFrame(kmodel.cluster_centers_).sort(0) #輸出聚類中心,並且排序(默認是隨機序的)
w = pd.rolling_mean(c, 2).iloc[1:] #相鄰兩項求中點,作爲邊界點
w = [0] + list(w[0]) + [data.max()] #把首末邊界點加上
d3 = pd.cut(data, w, labels = range(k))

def cluster_plot(d, k): #自定義作圖函數來顯示聚類結果
  import matplotlib.pyplot as plt
  plt.rcParams['font.sans-serif'] = ['SimHei'] #用來正常顯示中文標籤
  plt.rcParams['axes.unicode_minus'] = False #用來正常顯示負號
  
  plt.figure(figsize = (8, 3))
  for j in range(0, k):
    plt.plot(data[d==j], [j for i in d[d==j]], 'o')
  
  plt.ylim(-0.5, k-0.5)
  return plt

cluster_plot(d1, k).show()

cluster_plot(d2, k).show()
cluster_plot(d3, k).show()

運行無限報錯。回頭再來試試。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章