pandas數據處理進階(二)

一、數據去重

import pandas as pd

# 對數據進行去重---真實的數據
# 加載數據
detail = pd.read_excel("./meal_order_detail.xlsx")
print("detail :\n", detail)
# print(detail.shape)
print("*" * 80)

# 對amounts  進行去重,拿到 菜 的單價數據--來評估 這家餐廳的消費水平預估

# subset --指定要去重的數據
#  只有同列 才能進行去重
# res = detail.drop_duplicates(subset='amounts',inplace=False)

# print(res.shape)

# 相關性的衡量.corr()

# 衡量 ---counts  與  amounts 之間的相關性
#  [-1,1]之間
# 0 < corr 正相關
# 0 > corr 負相關
#  method  =  默認是皮爾遜相關係數
#  {'pearson', 'kendall', 'spearman'}
print("counts  與  amounts 之間的相關性:\n", detail.loc[:, ['counts', 'amounts']].corr())
print("counts  與  amounts 之間的相關性:\n", detail.loc[:, ['counts', 'amounts']].corr(method='spearman'))

二、dataframe拼接

import pandas as pd

# 加載數據
# data_1 = pd.read_excel("concat數據拼接.xlsx",sheetname=0)
# data_2 = pd.read_excel("concat數據拼接.xlsx",sheetname=1)
#
# print("data_1:\n",data_1)
# print("data_2:\n",data_2)

# 利用concat 進行拼接 ---沒有左右連接 (左右連接 只有主鍵拼接纔有)
# outer 代表外連接- 在行的方向上,直接拼接,列的方向上求列的並集
# print(pd.concat((data_1,data_2),axis=0,join='outer'))
# inner 代表內連接- 在行的方向上,直接拼接,列的方向上求列的交集
# print(pd.concat((data_1,data_2),axis=0,join='inner'))

# outer 代表外連接- 在列的方向上,直接拼接,行的方向上求列的並集
# print(pd.concat((data_1,data_2),axis=1,join='outer'))
# inner 代表外連接- 在列的方向上,直接拼接,行的方向上求列的交集
# print(pd.concat((data_1,data_2),axis=1,join='inner'))


# 主鍵拼接 ---沒有行方向的拼接
# 加載數據
# data_1 = pd.read_excel("./merge拼接數據.xlsx",sheetname=0)
# data_2 = pd.read_excel("./merge拼接數據.xlsx",sheetname=1)
#
# print("data_1:\n",data_1)
# print("data_2:\n",data_2)


#  how  = {'left', 'right', 'outer', 'inner'}
# on  就是 值一樣的列
# outer -  外連接  key值的列 求並集,沒有值的key  用NAN填充
# print(pd.merge(left=data_1,right=data_2,how='outer',on='key'))
# inner -  內連接  key值的列 求交集,沒有的數據的key  刪除
# print(pd.merge(left=data_1,right=data_2,how='inner',on='key'))
#  left  ---left outer 左外連接 ---外連接,以左表爲主
# key 列只關係 左表,右表不關心
# print(pd.merge(left=data_1,right=data_2,how='left',on='key'))
# right  right outer 右外連接
# key 列只關係 右表,左表不關心
# print(pd.merge(left=data_1,right=data_2,how='right',on='key'))


# 特殊情況
# 左表的列的名稱 與右表的列的名稱 沒有一樣的,但是裏面的數據是一樣
data_1 = pd.read_excel("./merge拼接數據1.xlsx",sheetname=0)
data_2 = pd.read_excel("./merge拼接數據1.xlsx",sheetname=1)
#
# print("data_1:\n",data_1)
# print("data_2:\n",data_2)


print(pd.merge(left=data_1,right=data_2,how='outer',left_on='key_l',right_on='key_r'))
print(pd.merge(left=data_1,right=data_2,how='inner',left_on='key_l',right_on='key_r'))
print(pd.merge(left=data_1,right=data_2,how='left',left_on='key_l',right_on='key_r'))
print(pd.merge(left=data_1,right=data_2,how='right',left_on='key_l',right_on='key_r'))

# join

三、數據填充

import pandas as pd

# # 加載數據
#
data_1 = pd.read_excel("./數據填充.xlsx",sheetname=0)
data_2 = pd.read_excel("./數據填充.xlsx",sheetname=1)
# print("data_1:\n",data_1)
# print("data_2:\n",data_2)
# print("*"*80)
# # 使用表二來填充表一
res = data_1.combine_first(data_2)
print(res)

四、缺失值處理(刪除法,填充法,插值法)

import pandas as pd
import numpy as np

# 加載數據
# data = pd.read_excel('./qs.xlsx')
# print("data:\n",data)
# print("data 的數據類型:\n",data.dtypes)
#
# print("*"*80)

# 如何確定數據裏面含有缺失值---缺失值檢測
# isnull   缺失值 返回T
# notnll  缺失值返回F
# 推薦使用  isnull + sum 來判斷缺失值
# print(data.isnull().sum())
# print("*"*80)
# print(data.notnull().sum())

# 1、刪除法--dropna
# 遇到缺失值就刪除---按行、按列刪除
# axis 指定刪除的軸
# how  指定刪除的方式 ---any只要有缺失值,就刪除
# how  指定刪除的方式 ---all只有整列或者整行都是缺失值,才刪除
# inplace 指定是否對原來產生影響
# data.dropna(axis=0,how='any',inplace=True)
# data.dropna(axis=1,how='any',inplace=True)
# data.dropna(axis=0,how='all',inplace=True)
# print(data)

#  對於刪除法,容易改變數據結構,容易造成大量數據丟失。
# 只有 行 或者列 大部分爲缺失值,我們才進行刪除
# 或者  行、列的數據對結果不重要 才進行刪除
# 2、填充法
# 對於數值型數據---可以均值、中位數、衆數來填充
# 對於類別型數據---可以使用衆數來填充
# mode = data.loc[:,'商品ID'].mode()[0]
# print(mode)
# data.loc[:,'商品ID'].fillna(value=mode,inplace=True)
# data.loc[:,'類別ID'].fillna(value=data.loc[:,'類別ID'].mode()[0],inplace=True)
# data.loc[:,'門店編號'].fillna(value=data.loc[:,'門店編號'].mode()[0],inplace=True)
# print("*"*80)
# print(data)

# 只要我們填充之後 對結果影響不是很大的情況下,就可以使用。
#  *
#  如果 是一些不能直接處理的缺失值,先轉化爲能處理的缺失值
# 這裏的缺失值 ---np.nan類型 ----float類型
# print(type(np.nan))
# data.replace(to_replace="*",value=np.nan,inplace=True)
# print(data)
# 刪除、填充都能進行
# 3、插值法
# 給合適的位置 插上合適的值
x = np.array([1, 2, 3, 4, 5, 8, 9])  #
y = np.array([3, 5, 7, 9, 11, 17, 19])  # y = 2* x + 1
z = np.array([2, 8, 18, 32, 50, 128, 162])  # z = 2 * x^2
#  線性插值、 多項式插值、樣條插值
# 線性插值 ---擬合線性關係進行插值
# from  scipy.interpolate  import  interp1d
# line1 = interp1d(x,y,kind='linear')
# line2 = interp1d(x,z,kind='linear')
# print(line1([6,7])) #  [ 13.  15.]
# print(line2([6,7])) # [  76.  102.]
# 多項式插值---牛頓插值法、拉格朗日插值法
# 擬合牛頓多項式 與 拉格朗日多項式
# from  scipy.interpolate import  lagrange
# la1 =  lagrange(x,y)
# la2 =  lagrange(x,z)
#
# print(la1([6,7])) # [ 13.  15.]
# print(la2([6,7])) # [ 72.  98.]
# 樣條插值--- 擬合曲線關係進行插值
from scipy.interpolate import spline

print(spline(xk=x, yk=y, xnew=np.array([6, 7])))  # [ 13.  15.]
print(spline(xk=x, yk=z, xnew=np.array([6, 7])))  # [ 72.  98.]

#  對於線性關係的數據 ---線性插值比較準確,多項式插值與 樣條插值都不錯,
# 如果是線性關係的數據----都可以使用

# 對於非線性數據---線性插值效果較差,多項式插值與樣條插值效果較好
# 如果是非線性關係的數據,---推薦使用多項式插值與樣條插值

五、異常值處理

import pandas as pd
import numpy as np


#  根據正太分佈得出 99.73%的數據都在[u-3sigma ,u+3sigma ]之間,那麼我們人爲超出這個區間的數據爲異常值

# 剔除異常值----保留數據在[u-3sigma ,u+3sigma ]之間
#
def three_sigma(data):
    """
    進行3 sigma異常值剔除
    :param data: 傳入的數據
    :return: 剔除之後的數據 或者剔除異常值之後的行索引名稱
    """
    bool_id_1 = (data.mean() - 3 * data.std()) <= data
    bool_id_2 = (data.mean() + 3 * data.std()) >= data

    bool_num = bool_id_1 & bool_id_2

    return bool_num


#
# # 以 detail 爲例 展示以amounts 進行異常值剔除,查看detail結果
# 加載數據
detail = pd.read_excel("./meal_order_detail.xlsx", sheetname=0)

print("detail:\n", detail)
print("detail 的列名:\n", detail.columns)

print("*" * 80)
#
# # 調用函數進行detail 中 amounts 的異常值剔除
#
bool_num = three_sigma(detail.loc[:, 'amounts'])
#
# # 獲取正常的detail
detail = detail.loc[bool_num, :]


#
#
# print(detail.shape)

# 箱線圖分析
# arr = pd.Series(np.array([1,2,3,4,5,6,7,8,9,10]))
# print(arr.quantile(0.5))
#  75 % 的數  qu
#  25% 的數  ql

# iqr = qu - ql

# 上限:qu + 1.5*iqr
# 下限 :ql - 1.5*iqr

def box_analysis(data):
    """
    進行箱線圖分析,剔除異常值
    :param data: series
    :return: bool數組
    """
    qu = data.quantile(0.75)
    # print(qu)
    ql = data.quantile(0.25)
    # print(ql)

    iqr = qu - ql

    # 上限
    up = qu + 1.5 * iqr
    #  下限
    low = ql - 1.5 * iqr

    # 進行比較運算
    bool_id_1 = data <= up
    bool_id_2 = data >= low

    bool_num = bool_id_1 & bool_id_2

    return bool_num


bool_num = box_analysis(detail.loc[:, 'amounts'])

detail = detail.loc[bool_num, :]

print(detail.shape)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章