python数据分析实战---数据处理

数据处理

缺失值处理

数据缺失主要包括记录缺失和字段信息缺失等情况,其对数据分析会有较大影响,导致结果不确定性更加显著

1.判断是否有缺失值

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import stats
% matplotlib inline

# 判断是否有缺失值数据 - isnull,notnull
# isnull:缺失值为True,非缺失值为False
# notnull:缺失值为False,非缺失值为True

s = pd.Series([12,33,45,23,np.nan,np.nan,66,54,np.nan,99])
df = pd.DataFrame({‘value1‘:[12,33,45,23,np.nan,np.nan,66,54,np.nan,99,190],
                  ‘value2‘:[‘a‘,‘b‘,‘c‘,‘d‘,‘e‘,np.nan,np.nan,‘f‘,‘g‘,np.nan,‘g‘]})
# 创建数据

print(s.isnull())  # Series直接判断是否是缺失值,返回一个Series
print(df.notnull())  # Dataframe直接判断是否是缺失值,返回一个Series
print(df[‘value1‘].notnull())  # 通过索引判断
print(‘------‘)

s2 = s[s.isnull() == False]
df2 = df[df[‘value2‘].notnull()]    # 注意和 df2 = df[df[‘value2‘].notnull()] [‘value1‘] 的区别
print(s2)
print(df2)
# 筛选非缺失值

2.删除缺失值

# 删除缺失值 - dropna

s = pd.Series([12,33,45,23,np.nan,np.nan,66,54,np.nan,99])
df = pd.DataFrame({‘value1‘:[12,33,45,23,np.nan,np.nan,66,54,np.nan,99,190],
                  ‘value2‘:[‘a‘,‘b‘,‘c‘,‘d‘,‘e‘,np.nan,np.nan,‘f‘,‘g‘,np.nan,‘g‘]})
# 创建数据

s.dropna(inplace = True)
df2 = df[‘value1‘].dropna()
print(s)
print(df2)
# drop方法:可直接用于Series,Dataframe
# 注意inplace参数,默认False → 生成新的值

3.填充、替换缺失值

# 填充/替换缺失数据 - fillna、replace

s = pd.Series([12,33,45,23,np.nan,np.nan,66,54,np.nan,99])
df = pd.DataFrame({‘value1‘:[12,33,45,23,np.nan,np.nan,66,54,np.nan,99,190],
                  ‘value2‘:[‘a‘,‘b‘,‘c‘,‘d‘,‘e‘,np.nan,np.nan,‘f‘,‘g‘,np.nan,‘g‘]})
# 创建数据

s.fillna(0,inplace = True)
print(s)
print(‘------‘)
# s.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)
# value:填充值
# 注意inplace参数

df[‘value1‘].fillna(method = ‘pad‘,inplace = True)
print(df)
print(‘------‘)
# method参数:
# pad / ffill → 用之前的数据填充
# backfill / bfill → 用之后的数据填充 

s = pd.Series([1,1,1,1,2,2,2,3,4,5,np.nan,np.nan,66,54,np.nan,99])
s.replace(np.nan,‘缺失数据‘,inplace = True)
print(s)
print(‘------‘)
# df.replace(to_replace=None, value=None, inplace=False, limit=None, regex=False, method=‘pad‘, axis=None)
# to_replace → 被替换的值
# value → 替换值

s.replace([1,2,3],np.nan,inplace = True)
print(s)
# 多值用np.nan代替

4.缺失值插补

# 缺失值插补
# 几种思路:均值/中位数/众数插补、临近值插补、插值法
# (1)均值/中位数/众数插补

s = pd.Series([1,2,3,np.nan,3,4,5,5,5,5,np.nan,np.nan,6,6,7,12,2,np.nan,3,4])
#print(s)
print(‘------‘)
# 创建数据

u = s.mean()     # 均值
me = s.median()  # 中位数
mod = s.mode()   # 众数
print(‘均值为:%.2f, 中位数为:%.2f‘ % (u,me))
print(‘众数为:‘, mod.tolist())
print(‘------‘)
# 分别求出均值/中位数/众数

s.fillna(u,inplace = True)
print(s)
# 用均值填补

# 缺失值插补
# 几种思路:均值/中位数/众数插补、临近值插补、插值法
# (2)临近值插补

s = pd.Series([1,2,3,np.nan,3,4,5,5,5,5,np.nan,np.nan,6,6,7,12,2,np.nan,3,4])
#print(s)
print(‘------‘)
# 创建数据

s.fillna(method = ‘ffill‘,inplace = True)
print(s)
# 用前值插补

# 缺失值插补
# 几种思路:均值/中位数/众数插补、临近值插补、插值法
# (3)插值法 —— 拉格朗日插值法

from scipy.interpolate import lagrange
x = [3, 6, 9]
y = [10, 8, 4]
print(lagrange(x,y))
print(type(lagrange(x,y)))
# 的输出值为的是多项式的n个系数
# 这里输出3个值,分别为a0,a1,a2
# y = a0 * x**2 + a1 * x + a2 → y = -0.11111111 * x**2 + 0.33333333 * x + 10

print(‘插值10为:%.2f‘ % lagrange(x,y)(10))
print(‘------‘)
# -0.11111111*100 + 0.33333333*10 + 10 = -11.11111111 + 3.33333333 +10 = 2.22222222

# 缺失值插补
# 几种思路:均值/中位数/众数插补、临近值插补、插值法
# (3)插值法 —— 拉格朗日插值法,实际运用

data = pd.Series(np.random.rand(100)*100)
data[3,6,33,56,45,66,67,80,90] = np.nan
print(data.head())
print(‘总数据量:%i‘ % len(data))
print(‘------‘)
# 创建数据

data_na = data[data.isnull()]
print(‘缺失值数据量:%i‘ % len(data_na))
print(‘缺失数据占比:%.2f%%‘ % (len(data_na) / len(data) * 100))
# 缺失值的数量

data_c = data.fillna(data.median())  #  中位数填充缺失值
fig,axes = plt.subplots(1,4,figsize = (20,5))
data.plot.box(ax = axes[0],grid = True,title = ‘数据分布‘)
data.plot(kind = ‘kde‘,style = ‘--r‘,ax = axes[1],grid = True,title = ‘删除缺失值‘,xlim = [-50,150])
data_c.plot(kind = ‘kde‘,style = ‘--b‘,ax = axes[2],grid = True,title = ‘缺失值填充中位数‘,xlim = [-50,150])
# 密度图查看缺失值情况

def na_c(s,n,k=5):
    y = s[list(range(n-k,n+1+k))] # 取数
    y = y[y.notnull()]  # 剔除空值
    return(lagrange(y.index,list(y))(n))
# 创建函数,做插值,由于数据量原因,以空值前后5个数据(共10个数据)为例做插值

na_re = []
for i in range(len(data)):
    if data.isnull()[i]:
        data[i] = na_c(data,i)
        print(na_c(data,i))
        na_re.append(data[i])
data.dropna(inplace=True)  # 清除插值后仍存在的缺失值
data.plot(kind = ‘kde‘,style = ‘--k‘,ax = axes[3],grid = True,title = ‘拉格朗日插值后‘,xlim = [-50,150])
print(‘finished!‘)
# 缺失值插值

异常值处理

异常值是指样本中的个别值,其数值明显偏离其余的观测值。
异常值也称离群点,异常值的分析也称为离群点的分析

1.3σ原则:如果数据服从正态分布,异常值被定义为一组测定值中与平均值的偏差超过3倍的值 → p(|x - μ| > 3σ) ≤ 0.003

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import stats
% matplotlib inline

data = pd.Series(np.random.randn(10000)*100)
# 创建数据

u = data.mean()  # 计算均值
std = data.std()  # 计算标准差
stats.kstest(data, ‘norm‘, (u, std))
print(‘均值为:%.3f,标准差为:%.3f‘ % (u,std))
print(‘------‘)
# 正态性检验

fig = plt.figure(figsize = (10,6))
ax1 = fig.add_subplot(2,1,1)
data.plot(kind = ‘kde‘,grid = True,style = ‘-k‘,title = ‘密度曲线‘)
plt.axvline(3*std,hold=None,color=‘r‘,linestyle="--",alpha=0.8)
plt.axvline(-3*std,hold=None,color=‘r‘,linestyle="--",alpha=0.8)
# 绘制数据密度曲线

ax2 = fig.add_subplot(2,1,2)
error = data[np.abs(data - u) > 3*std]
data_c = data[np.abs(data - u) <= 3*std]
print(‘异常值共%i条‘ % len(error))
# 筛选出异常值error、剔除异常值之后的数据data_c

plt.scatter(data_c.index,data_c,color = ‘k‘,marker=‘.‘,alpha = 0.3)
plt.scatter(error.index,error,color = ‘r‘,marker=‘.‘,alpha = 0.5)
plt.xlim([-10,10010])
plt.grid()
# 图表表达

2.箱型图分析

fig = plt.figure(figsize = (10,6))
ax1 = fig.add_subplot(2,1,1)
color = dict(boxes=‘DarkGreen‘, whiskers=‘DarkOrange‘, medians=‘DarkBlue‘, caps=‘Gray‘)
data.plot.box(vert=False, grid = True,color = color,ax = ax1,label = ‘样本数据‘)
# 箱型图看数据分布情况
# 以内限为界

s = data.describe()
print(s)
print(‘------‘)
# 基本统计量

q1 = s[‘25%‘]
q3 = s[‘75%‘]
iqr = q3 - q1
mi = q1 - 1.5*iqr
ma = q3 + 1.5*iqr
print(‘分位差为:%.3f,下限为:%.3f,上限为:%.3f‘ % (iqr,mi,ma))
print(‘------‘)
# 计算分位差

ax2 = fig.add_subplot(2,1,2)
error = data[(data < mi) | (data > ma)]
data_c = data[(data >= mi) & (data <= ma)]
print(‘异常值共%i条‘ % len(error))
# 筛选出异常值error、剔除异常值之后的数据data_c

plt.scatter(data_c.index,data_c,color = ‘k‘,marker=‘.‘,alpha = 0.3)
plt.scatter(error.index,error,color = ‘r‘,marker=‘.‘,alpha = 0.5)
plt.xlim([-10,10010])
plt.grid()
# 图表表达

数据归一化(标准化)

数据的标准化(normalization)是将数据按比例缩放,使之落入一个小的特定区间。
在某些比较和评价的指标处理中经常会用到,去除数据的单位限制,将其转化为无量纲的纯数值,便于不同单位或量级的指标能够进行比较和加权

最典型的就是数据的归一化处理,即将数据统一映射到[0,1]区间上

1.0-1标准化

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
% matplotlib inline

# 数据标准化
# (1)0-1标准化
# 将数据的最大最小值记录下来,并通过Max-Min作为基数(即Min=0,Max=1)进行数据的归一化处理
# x = (x - Min) / (Max - Min)

df = pd.DataFrame({"value1":np.random.rand(10)*20,
                  ‘value2‘:np.random.rand(10)*100})
print(df.head())
print(‘------‘)
# 创建数据

def data_norm(df,*cols):
    df_n = df.copy()
    for col in cols:
        ma = df_n[col].max()
        mi = df_n[col].min()
        df_n[col + ‘_n‘] = (df_n[col] - mi) / (ma - mi)
    return(df_n)
# 创建函数,标准化数据

df_n = data_norm(df,‘value1‘,‘value2‘)
print(df_n.head())
# 标准化数据

2.Z-score标准化

# 数据标准化
# (2)Z-score标准化
# Z分数(z-score),是一个分数与平均数的差再除以标准差的过程 → z=(x-μ)/σ,其中x为某一具体分数,μ为平均数,σ为标准差
# Z值的量代表着原始分数和母体平均值之间的距离,是以标准差为单位计算。在原始分数低于平均值时Z则为负数,反之则为正数
# 数学意义:一个给定分数距离平均数多少个标准差?

df = pd.DataFrame({"value1":np.random.rand(10) * 100,
                  ‘value2‘:np.random.rand(10) * 100})
print(df.head())
print(‘------‘)
# 创建数据

def data_Znorm(df, *cols):
    df_n = df.copy()
    for col in cols:
        u = df_n[col].mean()
        std = df_n[col].std()
        df_n[col + ‘_Zn‘] = (df_n[col] - u) / std
    return(df_n)
# 创建函数,标准化数据

df_z = data_Znorm(df,‘value1‘,‘value2‘)
u_z = df_z[‘value1_Zn‘].mean()
std_z = df_z[‘value1_Zn‘].std()
print(df_z)
print(‘标准化后value1的均值为:%.2f, 标准差为:%.2f‘ % (u_z, std_z))
# 标准化数据
# 经过处理的数据符合标准正态分布,即均值为0,标准差为1

# 什么情况用Z-score标准化:
# 在分类、聚类算法中,需要使用距离来度量相似性的时候,Z-score表现更好

案例应用

# 八类产品的两个指标value1,value2,其中value1权重为0.6,value2权重为0.4
# 通过0-1标准化,判断哪个产品综合指标状况最好

df = pd.DataFrame({"value1":np.random.rand(10) * 30,
                  ‘value2‘:np.random.rand(10) * 100},
                 index = list(‘ABCDEFGHIJ‘))
#print(df.head())
#print(‘------‘)
# 创建数据"

df_n1 = data_norm(df,‘value1‘,‘value2‘)
# 进行标准化处理

df_n1[‘f‘] = df_n1[‘value1_n‘] * 0.6 + df_n1[‘value2_n‘] * 0.4
df_n1.sort_values(by = ‘f‘,inplace=True,ascending=False)
df_n1[‘f‘].plot(kind = ‘line‘, style = ‘--.k‘, alpha = 0.8, grid = True)
df_n1
# 查看综合指标状况

  

数据连续属性离散化

连续属性变换成分类属性,即连续属性离散化
在数值的取值范围内设定若干个离散划分点,将取值范围划分为一些离散化的区间,最后用不同的符号或整数值代表每个子区间中的数据值

1.等宽法

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
% matplotlib inline

# 等宽法 → 将数据均匀划分成n等份,每份的间距相等
# cut方法

ages=[20,22,25,27,21,23,37,31,61,45,41,32]
# 有一组人员年龄数据,希望将这些数据划分为“18到25”,“26到35”,“36到60”,“60以上”几个面元

bins = [18,25,35,60,100]
cats = pd.cut(ages,bins)
print(cats)
print(type(cats))
print(‘-------‘)
# 返回的是一个特殊的Categorical对象 → 一组表示面元名称的字符串

print(cats.codes, type(cats.codes))  # 0-3对应分组后的四个区间,用代号来注释数据对应区间,结果为ndarray
print(cats.categories, type(cats.categories))  # 四个区间,结果为index
print(pd.value_counts(cats))  # 按照区间计数
print(‘-------‘)
# cut结果含有一个表示不同分类名称的层级数组以及一个年龄数据进行标号的代号属性

print(pd.cut(ages,[18,26,36,61,100],right=False))
print(‘-------‘)
# 通过right函数修改闭端,默认为True

group_names=[‘Youth‘,‘YoungAdult‘,‘MiddleAged‘,‘Senior‘]
print(pd.cut(ages,bins,labels=group_names))
print(‘-------‘)
# 可以设置自己的区间名称,用labels参数

df = pd.DataFrame({‘ages‘:ages})
group_names=[‘Youth‘,‘YoungAdult‘,‘MiddleAged‘,‘Senior‘]
s = pd.cut(df[‘ages‘],bins)  # 也可以 pd.cut(df[‘ages‘],5),将数据等分为5份
df[‘label‘] = s
cut_counts = s.value_counts(sort=False)
print(df)
print(cut_counts)
# 对一个Dataframe数据进行离散化,并计算各个区间的数据计数

plt.scatter(df.index,df[‘ages‘],cmap = ‘Reds‘,c = cats.codes)
plt.grid()
# 用散点图表示,其中颜色按照codes分类
# 注意codes是来自于Categorical对象

2.等频法

# 等频法 → 以相同数量的记录放进每个区间
# qcut方法

data = np.random.randn(1000)
s = pd.Series(data)
cats = pd.qcut(s,4)  # 按四分位数进行切割,可以试试 pd.qcut(data,10)
print(cats.head())
print(pd.value_counts(cats))
print(‘------‘)
# qcut → 根据样本分位数对数据进行面元划分,得到大小基本相等的面元,但并不能保证每个面元含有相同数据个数
# 也可以设置自定义的分位数(0到1之间的数值,包含端点) → pd.qcut(data1,[0,0.1,0.5,0.9,1])

plt.scatter(s.index,s,cmap = ‘Greens‘,c = pd.qcut(data,4).codes)
plt.xlim([0,1000])
plt.grid()
# 用散点图表示,其中颜色按照codes分类
# 注意codes是来自于Categorical对象

  

原文地址:https://www.cnblogs.com/garrett0220/p/11635822.html

时间: 2024-08-01 07:11:15

python数据分析实战---数据处理的相关文章

【python数据分析实战】电影票房数据分析(一)数据采集

目录 1.获取url 2.开始采集 3.存入mysql 本文是爬虫及可视化的练习项目,目标是爬取猫眼票房的全部数据并做可视化分析. 1.获取url 我们先打开猫眼票房http://piaofang.maoyan.com/dashboard?date=2019-10-22 ,查看当日票房信息, 但是在通过xpath对该url进行解析时发现获取不到数据. 于是按F12打开Chrome DevTool,按照如下步骤抓包 再打开获取到的url:http://pf.maoyan.com/second-bo

【python数据分析实战】电影票房数据分析(二)数据可视化

目录 图1 每年的月票房走势图 图2 年票房总值.上映影片总数及观影人次 图3 单片总票房及日均票房 图4 单片票房及上映月份关系图 在上一部分<[python数据分析实战]电影票房数据分析(一)数据采集> 已经获取到了2011年至今的票房数据,并保存在了mysql中. 本文将在实操中讲解如何将mysql中的数据抽取出来并做成动态可视化. 图1 每年的月票房走势图 第一张图,我们要看一下每月的票房走势,毫无疑问要做成折线图,将近10年的票房数据放在一张图上展示. 数据抽取: 采集到的票房数据是

python数据分析实战-第6章-深入pandas数据处理

第6章 深入pandas:数据处理 117 6.1 数据准备 117 合并 1234567891011 #merge是两个dataframe共同包含的项import numpy as npimport pandas as pdframe1 = pd.DataFrame( {'id':['ball','pencil','pen','mug','ashtray'], 'price': [12.33,11.44,33.21,13.23,33.62]})print(frame1)print()frame

python数据分析实战-第2章-ptyhon世界简介

第2章 Python世界简介 122.1 Python--编程语言 122.2 Python--解释器 132.2.1 Cython 142.2.2 Jython 142.2.3 PyPy 142.3 Python 2和Python 3 142.4 安装Python 152.5 Python发行版 152.5.1 Anaconda 152.5.2 Enthought Canopy 162.5.3 Python(x,y) 172.6 使用Python 172.6.1 Python shell 17

python数据分析实战-第9章-数据分析实例气象数据

第9章 数据分析实例--气象数据 2309.1 待检验的假设:靠海对气候的影响 2309.2 数据源 2339.3 用IPython Notebook做数据分析 2349.4 风向频率玫瑰图 2469.5 小结 251 123 import numpy as npimport pandas as pdimport datetime 1 ferrara = pd.read_json('http://api.openweathermap.org/data/2.5/history/city?q=Fer

python数据分析实战---基础准备

下载安装使用工具Anaconda https://www.anaconda.com/distribution/#download-section 安装完毕后,在开始找到spyder即可. python的编程基础 1.定义.变量.赋值 变量的命名规则,可以用a-z,A-Z,数字,下划线组成,首字母不能是数字或者下划线,变量名不能是python的保留字,大小写的赋值是不一样的. 2.数据类型 布尔型(与&.或|.非not).数值型.字符型 1 x = 1; 2 y = 2; 3 4 x + y 5

python数据分析实战-第7章-用matplotlib实现数据可视化

第7章 用matplotlib实现数据可视化 149 7.1 matplotlib库 149 7.2 安装 150 7.3 IPython和IPython QtConsole 150 7.4 matplotlib架构 151 7.4.1 Backend层 152 7.4.2 Artist层 152 7.4.3 Scripting层(pyplot) 153 7.4.4 pylab和pyplot 153 7.5 pyplot 154 7.5.1 生成一幅简单的交互式图表 154 123 import

python数据分析实战-第3章-numpy库

第3章 NumPy库 32 3.1 NumPy简史 32 3.2 NumPy安装 32 3.3 ndarray:NumPy库的心脏 33 1 import numpy as np 1 a = np.array([1, 2, 3]) 1 a array([1, 2, 3]) 1 type(a), a.dtype, a.ndim, a.size, a.shape, a.itemsize (numpy.ndarray, dtype('int64'), 1, 3, (3,), 8) 1 b = np.a

《Python数据分析实战》3 NumPy库

初始化数组 arr = np.array([[1,2],[3,4]]) arr = np.array([[1,2],[3,4]], dtype=complex) arr = np.zeros((3,4)) arr = np.ones((1,2)) arr = np.arange(4,10).reshape(2,3) arr = np.linspace(0,1,6)  #[0.0,0.2,0.4,0.6,0.8,1.0] arr = np.random.random(3) arr = np.ran