应用型|(转载)Pandas高级操作——缺失值处理、数据合并、数据离散化直方图

参考 https://blog.csdn.net/m0_38106113/article/details/82116683
1 缺失值处理 对于获取到的数据,总会有一些是缺少的,如果这些缺少的数据对于我们的接下来的工作无关紧要,就可以直接舍弃;而有作用的就要应该补齐。我们使用一些电影数据来说明接下来的操作,先看看电影数据的结构

import pandas as pd# 读取电影数据 movie = pd.read_csv("data/IMDB/IMDB-Movie-Data.csv")

应用型|(转载)Pandas高级操作——缺失值处理、数据合并、数据离散化直方图
文章图片

1.1 判断缺失值
首先判断是否空缺值
pd.notnull(movie)# 这个函数会把NaN的数值返回False,非NaN的数值返回True
pd.isnull(movie).head(10)# 这个函数会把NaN的数值返回True,非NaN的数值返回False
1.2 丢弃缺失值
对于不重要的数据可以直接舍弃
movie.size # 12000movie = movie.dropna()# 丢弃空缺的数据行movie.size # 10056

丢弃之后数量从12000变成了10056
1.3 替换缺失值
通常情况下缺失的只是一组数据的一小部分,这时候丢弃就是非常浪费的了,同时如果这组数据比较重要,那么丢弃就不可取,而是使用替换。
替换可以用中位数、众数、均值等替换,或者回归方程,最近值、固定值替换,高级一点可以使用拉格朗日插值法和牛顿插值法
import numpy as np# 读取电影数据 movie = pd.read_csv("data/IMDB/IMDB-Movie-Data.csv") np.any(pd.isnull(movie)) # True

# ①判断哪一列有缺失值 for col in movie.columns: # pd.isnull(movie[col])将当前列的缺失值转换为True,any()判断数组中是否至少有一个为True,是就返回True if (np.any(pd.isnull(movie[col]))): # 使用fillna()来填充缺失值,第一个参数的替换后的值,inplace参数表示是否修改原数据 movie[col].fillna(movie[col].mean(), inplace=True)

np.any(pd.isnull(movie))# 可以看到在变换之后any返回为False,说明已经没有缺失值了 # False

也有一些其他方法。用于判断是否空缺,比如pandas中的isna()函数
df[u'流量信号差分'].loc[pd.isna(df[u'流量信号差分'])] = 0

df[u'部件工作时长差分'][df[u'部件工作时长差分'].isna()] = 0


1.4 当缺失值不为NaN的时候
把它替换成NaN,如下面这组缺失值为?的数据
应用型|(转载)Pandas高级操作——缺失值处理、数据合并、数据离散化直方图
文章图片

这种情况下用any有缺失值但是不是NaN所以判断不出来
np.any(pd.isnull(wis))# False

那就先替换掉这个?,变成NaN
# 如果缺失值不是np.NaN首先替换成nan wis = wis.replace(to_replace='?', value=https://www.it610.com/article/np.NAN) np.any(pd.isnull(wis))# 再次查看是否有缺失值 True# 可以看到现在是有缺失值的

接下来在进行其他缺失值操作

2 数据的离散化 离散化的概念
  • 把连续的数据 分成几段, 处于某一段中的所有数据 忽略他们之间的区别
  • 离散化的作用
  • ① 可以降低数据属性的个数
  • ② 可以是数据稳定性更强
  • ③ 可以降低异常值对结果的影响
  • ④有一些算法 更适合处理离散的值 比如逻辑回归
案例:股票的涨跌幅离散化
我们对股票每日的”p_change”进行离散化
data = https://www.it610.com/article/pd.read_csv("data/stock_day/stock_day.csv") p_change= data['p_change'] p_change.head()

2018-02-272.68 2018-02-263.02 2018-02-232.42 2018-02-221.64 2018-02-142.05 Name: p_change, dtype: float64

2.1 使用qcut()进行离散化
【应用型|(转载)Pandas高级操作——缺失值处理、数据合并、数据离散化直方图】qcut会根据分组个数均匀分组
# 第一个参数为分组的依赖索引,第二个参数为分的组别 qcat = pd.qcut(data['p_change'], 10)qcat.value_counts()# 可见qcut会根据参数分成均匀的组别(5.27, 10.03]65 (0.26, 0.94]65 (-0.462, 0.26]65 (-10.031, -4.836]65 (2.938, 5.27]64 (1.738, 2.938]64 (-1.352, -0.462]64 (-2.444, -1.352]64 (-4.836, -2.444]64 (0.94, 1.738]63 Name: p_change, dtype: int64

2.2 使用cut()进行分组
cut()方法是根据自定义的分组区间来分组
bins=[-12,-8,-5,-3,0,3,5,8,12] cat = pd.cut(data['p_change'], bins)cat.value_counts()(0, 3]215 (-3, 0]188 (3, 5]57 (-5, -3]51 (5, 8]43 (-8, -5]34 (-12, -8]28 (8, 12]27 Name: p_change, dtype: int64

2.3 使用哑变量矩阵离散化
哑变量实际上就是生成数据与区间的ont-hot的dataframe格式
# 生成哑变量矩阵参数1 要生成哑变量矩阵的数据参数2 (可选)每一列的前缀 如果没有前缀就是 列名分组的区间 dummies = pd.get_dummies(cat,prefix='rise')


3 数据合并 3.1 concat 直接把表格堆叠在一起的合并方式
# concat数据合并参数1 要合并的所有数据的list参数2 按照行还是列进行合并 pd.concat([data,dummies],axis=1).head()

openhighcloselow volumeprice_changep_changema5 ma10ma20... v_ma20turnoverrise_(-12, -8]rise_(-8, -5]rise_(-5, -3]rise_(-3, 0]rise_(0, 3] rise_(3, 5] rise_(5, 8] rise_(8, 12] 2018-02-2723.5325.8824.1623.5395578.030.632.6822.94222.14222.875... 55576.112.3900001000 2018-02-2622.8023.7823.5322.8060985.110.693.0222.40621.95522.942... 56007.501.5300000100 2018-02-2322.8823.3722.8222.7152914.010.542.4221.93821.92923.022... 56372.851.3200001000 ·····

3.2 merge
用于dataframe数据连接,类似于mysql的表格连接,同样分为左连接,右连接,内连接,外连接
pd.merge(left, right, how=’inner’, on=None, left_on=None, right_on=None,left_index=False, right_index=False, sort=True,suffixes=(‘_x’, ‘_y’), copy=True, indicator=False,validate=None)
left:连接的左表
right:连接的右表
how:连接方式,分为right,left,inner,outer,默认是inner
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']}) leftABkey1key2 0A0B0K0K0 1A1B1K0K1 2A2B2K1K0 3A3B3K2K1rightCDkey1key2 0C0D0K0K0 1C1D1K1K0 2C2D2K1K0 3C3D3K2K0

现在对两个表进行连接
左连接
result = pd.merge(left, right, how='left', on=['key1', 'key2']) result# 左表全部保留,右表缺失的值会变成NaNABkey1key2CD 0A0B0K0K0C0D0 1A1B1K0K1NaN NaN 2A2B2K1K0C1D1 3A2B2K1K0C2D2 4A3B3K2K1NaN NaN

右连接
result = pd.merge(left, right, how='right', on=['key1', 'key2']) result# 右表全部保留,左表缺失的值会变成NaNABkey1key2CD 0A0B0K0K0C0D0 1A2B2K1K0C1D1 2A2B2K1K0C2D2 3NaN NaN K2K0C3D3

内连接
result = pd.merge(left, right, how='inner', on=['key1', 'key2']) result# 两个表都有的部分保留,缺失的舍弃ABkey1key2CD 0A0B0K0K0C0D0 1A2B2K1K0C1D1 2A2B2K1K0C2D2

外连接
result = pd.merge(left, right, how='outer', on=['key1', 'key2']) result# 两个表所有数据保留,缺失的用NaN替换ABkey1key2CD 0A0B0K0K0C0D0 1A1B1K0K1NaN NaN 2A2B2K1K0C1D1 3A2B2K1K0C2D2 4A3B3K2K1NaN NaN 5NaN NaN K2K0C3D3


4 分组和聚合 分组与聚合通常是分析数据的一种方式,通常与一些统计函数一起使用,查看数据的分组情况
4.1 什么是分组和聚合
4.2 实际操作
DataFrame.groupby(key, as_index=False)
key:分组的列数据,可以多个
as_index:分组的列在显示结果的时候是否作为索引 默认是使用分组的列作为索引
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]}) colcolorobjectprice1price2 0whitepen 5.564.75 1red pencil4.204.12 2greenpencil1.301.60 3red ashtray 0.560.75 4greenpen 2.753.15

进行分组,对颜色分组聚合后计算price1的平均值
col.groupby(['color'])['price1'].mean()color green2.025 red2.380 white5.560 Name: price1, dtype: float64

# 分组,数据的结构不变 col.groupby(['color'], as_index=False)['price1'].mean()colorprice1 0green2.025 1red 2.380 2white5.560


    推荐阅读