一、缺失值处理
1、缺失值处理思路
- 删除含有缺失值的样本
- 替换/插补(计算平均值、中位数填入)
2、如何处理NaN
- 判断数据是否为NaN:
- pd.isnull(df),pd.notnull(df)
- 存在缺失值NaN,并且是np.nan:
- 1、删除存在缺失值的:df.dropna(axis=‘rows’,inpalce=True)
- 2、替换缺失值:df.fillna(value,inplace=True)
- value:替换成的值
- inplace:True会修改原数据/False不替换修改原数据,生成新的对象
- 不是缺失值nan,有默认标记的
3、缺失值处理实例
import pandas as pd
import numpy as np
movie = pd.read_csv('IMDB-Movie-Data.csv')
# 1、判断是否存在缺失值
pd.isnull(movie)
# pd.notnull(movie)
np.any(pd.isnull(movie))
# 返回True说明数据中存在缺失值,或者np.all(pd.notnull(movie))
pd.isnull(movie).any()
# 返回字段为True的存在缺失值,或者pd.notnull(movie).all()
结果显示:
Rank False
Title False
Genre False
Description False
Director False
Actors False
Year False
Runtime (Minutes) False
Rating False
Votes False
Revenue (Millions) True
Metascore True
dtype: bool
# 2、缺失值处理
# 方法1:删除含有缺失值的样本
data1 = movie.dropna()
# 方法2:替换
# 含有缺失值的字段为
# Revenue (Millions) True
# Metascore True
movie['Revenue (Millions)'].fillna(movie['Revenue (Millions)'].mean(),inplace=True)
movie['Metascore'].fillna(movie['Metascore'].mean(),inplace=True)
pd.isnull(movie).any() #缺失值已经处理完毕,不存在缺失值
# 3、替换操作
data.replace(to_replace='?',value=np.nan)
二、数据离散化
1、为什么要离散化
- 连续属性离散化的目的是为了简化数据,数据离散化技术可以用来减少给定连续属性值的个数,离散化方法经常作为数据挖掘的工具。
2、如何实现数据的离散化
- 对数据进行分组
- 自动分组:sr=pd.qcut(data,bins)
- 自定义分组:sr=pd.cut(data,bins)
- 对数据进行分组将数据分组一般会与value_counts搭配使用
- series.value_counts():统计分组次数
- 对分好组的数据求哑变量(one-hot编码)
- pandas.get_dummies(data,prefix=None)
- data:array-like,Series or DataFrame
- prefix:分组名字
import pandas as pd
# 1、准备数据
data = pd.Series([165,174,160,180,159,163,192,184],index=['No1:165','No2:174','No3:160','No4:180','No5:159','No6:163','No7:192','No8:184'])
# 2、分组
# 自动分组
sr = pd.qcut(data,3)
# 自定义分组
bins = [150,165,180,195]
sr = pd.cut(data,bins)
# 查看每个区间的个数
sr.value_counts()
# 3、转换成one-hot编码
df_new = pd.get_dummies(sr,prefix='height')
三、合并
- 应用pd.concat实现数据合并——按位置拼接
- 应用pd.merge实现数据合并——按索引拼接
1、pd.concat按位置拼接
- pd.concat([data1,data2],axis=0/1)
# 水平拼接
pd.concat([sr,df_new],axis=1)
2、pd.merge按索引拼接
- pd.merge(left,right,how=‘inner’,on=None)
- left:左表
- right:右表
- how:连接方式,left左连接,right右连接,inner内连接,outer外连接
- on:索引字段
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']})
pd.merge(left,right,how='inner',on=['key1','key2'])
四、交叉表与透视表
- 找到、探索两个变量之间的关系
1、使用crosstab(交叉表)实现
- 交叉表:交叉表用于计算一列数据对于另外一列数据的分组个数(寻找两个列之间的关系)
- pd.crosstab(value1,value2)
stock = pd.read_csv('stock_day.csv')
# 星期数据以及涨跌幅是好是坏数据
# pd.crosstab(星期数据列,涨跌幅数据列)
# pandas日期类型
date = pd.to_datetime(stock.index)
# 添加星期数据列
stock['week'] = date.weekday
# date.yeer date.month 年月都可显示
# 准备涨跌幅数据列
stock['pona'] = np.where(stock['p_change']>0,1,0)
pd.crosstab(stock['week'],stock['pona'])
上表反映了星期几涨跌的个数,0跌1涨
data = pd.crosstab(stock['week'],stock['pona'])
# data / data.sum(axis=1) 这样除是按行的
data.div(data.sum(axis=1),axis=0)
data.div(data.sum(axis=1),axis=0).plot(kind = 'bar',stacked=True)
# stacked=True 是否堆叠
2、使用pivot_table(透视表)实现
- DataFrame.pivot_table([],index=[])
stock.pivot_table(['pona'],index=['week'])
五、分组与聚合
- 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]})
# 进行分组,对颜色分组,price1进行聚合
# 用dataframe的方法进行分组
col.groupby(by = 'color')['price1'].max()
# 先对color进行分组,然后找每个颜色里的price1的最大值,by可省略
# 用series的方法进行分组
col['price1'].groupby(col['color']).max()
# 1、读取数据
starbucks = pd.read_csv('directory.csv')
# 2、按国家进行分组,求出每个国家的星巴克零售店数量
starbucks.groupby('Country').count()['Brand'].sort_values(ascending=False)[:10].plot(kind = 'bar',,figsize=[20,8],fontsize=40)
# 先分组,然后求每个组的和,Brand的series降序,取前十个画图
# 3、假设我们加入省市一起进行分组
starbucks.groupby(by=['Country','State/Province']).count()