【分析工具】Python之Pandas02

 

2.7数据的处理

2.7.1空数据的处理

2.7.1.1空数据类型

  • None:是python自带的一种空数据,object,运算起来特别慢,不能进行任何的运算。
  • NaN:Numpy自带的空数据类型,浮点型,可参与运算,运算之后的结果总是NaN,在pandas中NAN和None都被认为是空数据。

2.7.1.2空数据的判断

a=np.array([1,2,np.nan])
np.isnan(a)  # numpy中空值的判断方法

s=pd.Series([1,2,None])
s.isnull()  # pandas中空值的判断方法

df=pd.DataFrame([[1,2,np.nan],[[1,np.nan,2]]])
df.isnull()

2.7.1.3查看空数据

s=pd.Series([1,2,None,np.nan])
s[s.isnull()].index   # 取出空的下标

2.7.1.4删除空数据

cond=df.isnull().any(axis=1)  # 通过isnull()判断是否为空,是空返回True,否则False,使用any()通过axis=1指定只要一行当中有一个值为null那就认为是True
null_index=df[cond].index  # 获取为空的索引
df1=df.drop(null_index)  # 使用drop从df中删除空的数据样本
df1.info()  # 查看数据中是否还存在空数据

2.7.1.5空数据填充

空数据不一定都删除,当数据量不大的时候,尽量补全,正太分布时用平均数补齐.通过我们使用fillna()函数对其进行补全,参数为:

  • value需要填充的值
  • method:填充的方法
  • axis:轴,按行填充还是按列填充
  • inplace:是否直接在原来的数据中替换
  • limit:每行或者每列最多替换limit个空值
df.fillna(value='不存在')
df.fillna(value=df.mean(axis=0))  # 填充每一列的平均值
df.fillna(value=df.median(axis=0))  # 中位数
df.fillna(value=df.max(axis=0))
df.fillna(value=df.min(axis=0))
df.fillna(method='ffill')  # 填充前值
df.fillna(method='bfill')  # 填充后值

2.7.1.6空值运算

a=np.array([1,2,np.nan])
np.nansum(a)  # 3  # 空值不计数
np.nanmean(a)  #1.5  # 空值不计数
a.mean()  # nan 空值计数

2.7.2重复数据处理

2.7.2.1Series祛除重复数据

s=pd.Series([1,2,3,4,3,4])
s.unique()

2.7.2.2DataFrame祛除重复数据

方法一:函数drop_duplicates()

df1.drop_duplicates(inplace=False)

方法二:drop()和duplicated()分开使用

cond=df1.duplicated()  # 判断是否重复
_index=df1[cond].index  # 获取重复值的所有
df1.drop(_index)  # 根据索引进行删除

2.7.3数据映射函数

map、replace、apply、transform和rename的使用以及联系和区别

2.7.3.1map()函数

应用到所有元素中,不满足替换条件就赋值为None,适用于连续型,替换规则一般为函数。

df1 = pd.DataFrame(
    data=np.random.randint(-50,101,size = (20,3)),
    columns=['Python','En','Math']
)
def convert(x):
    if x>85:
        return '优秀'
    elif x>70:
        return '良好'
    elif x>60:
        return '及格'
    elif x>0:
        return '不及格'
level=df1.mean(axis=1).map(convert)  # 数据映射
df1['等级']=level  # 将Series数据存放到DataFrame数据中
df1['等级'].value_counts()  # 分组统计
df1

2.7.3.2replace()函数

作用于每个元素,适用于离散型数据,替换内容一般为字典类型,不满足替换条件就不进行替换

df2= pd.DataFrame(
    data=np.random.randint(-50,101,size = (20,3)),
    columns=['Python','En','Math']
)
df2['sex']=pd.Series(np.random.randint(0,3,size=20))
df2['sex']=df2['sex'].replace({0:'female',1:'male'})

2.7.3.3rename()函数

  • df1.rename({'等级':'level'},axis=1)
  • df1.set_index()

2.8数据的拼接融合

2.8.1Numpy中数据的级联

使用axis=0指定为上下合并,axis=1指定为左右合并.

nd1=np.array([[1,2,3],[4,5,6]])
np.concatenate([nd1,nd1,nd1],axis=0)

2.8.2Pandas数据级联

2.8.2.1concat()函数

该函数通过axis=0指定为上下级联,axis=1表示左右级联,参数ingore_index可以忽原索引,join指定是内连接inner默认是外连接outer.

上下连接:

df1=pd.DataFrame(
    data=np.random.randint(0,150,size=(8,4)),
    columns=['Python','Java','C','C++']
)
df2=pd.DataFrame(
    data=np.random.randint(0,150,size=(3,4)),
    columns=['Python','Java','C','C++']
)
df2['平均值']=df2.mean(axis=1)
pd.concat([df1,df2],axis=0,ignore_index=True)

左右连接:

df1=pd.DataFrame(
    data=np.random.randint(0,150,size=(3,4)),
    columns=['Python','Java','C','C++']
)
df2=pd.DataFrame(
    data=np.random.randint(0,150,size=(4,4)),
    columns=['语文','数学','英语','理综']
)
pd.concat([df1,df2],axis=1,join='inner')

2.8.2.2merge()函数

该函数专门用来左右连接,下面是该函数的参数介绍:

  • df1,  # 表一
  • df2,  # 表二
  • how='inner'  # inner保留左表和右表共同的数据,outer:都保留,left保留左边,right保留右边
  • left_on='_id',# 左表和右表没有共同的字段的时候,我们通过指定字段进行融合,左表字段
  • right_on='id',  # 右表字段
  • on='age',  # 如果两个表有很多共同的字段的时候,我们可以指定某个具体的字段进行合并
  • suffixes=('_pre1','_pre2'),  # 指定共同字段合并之后就会出现两个age,为了区分,我们在其后面添加后缀
  • sort=True,  # 对数据进行排序
  • left_index=True,  # 一般左右一起连用,如果开启,就表示根据左右索引进行关联
  • right_index=True,  
df1 = DataFrame({'name':['张三','张三','李四'],'salary':[12000,15000,18000]})
df2 = DataFrame({'name':['张三','张三','李四'],'address':['河北','河南','山西']})
pd.merge(df1,df2)

2.8.2.3join函数

该函数是merge的一个简化版本.

  • on='name' # 指定需要关联的属性
  • how='inner' #  'left', 'right', 'outer', 'inner'  四个连接方式
  • lsuffix='1',  # 左边的后缀
  • rsuffix='2', # 右表后缀
  • sort=True,   # 排序 

2.9数据聚合操作

2.9.1指定属性排序

方式一:自定义方法排序

df1 = pd.DataFrame(
    data=np.random.randint(0,150,size=(8,4)),
    index=list('ABCDEFGH'),
    columns=['python','java','php','mysql'],
)
df1['总分']=df1.mean(axis=1)
sort_index=df3['总分'].argsort()  # 获取排序的下标
df3.iloc[sort_index]  # 取出排序之后的数据

方法二:使用Pandas中提供的方法排序

df1.sort_index()  # 通过索引排序
df1.sort_values(by='总分',axis=0)  # 指定具体列排序
df1.sort_values(by='H',axis=1)  # 指定行排序

方法三:指定索引排序

df.take(index)
df.iloc[index]

2.9.2异常值检测

  • describe():描述性统计量,随机种子random.seed(0)
  • std():求每个对象的标准差
  • any():借助any函数对每一列应用筛选条件.axis=0对列进行判断.eg:df2.isnull().any(axis=1) # 判断每一行有没有空数据,有的话返回True
  • query('过滤条件'):举个例子:df1.query('总分>60' and 'Python>80')或者df1.query('python>java')
  • info() 查看数据总体情况

2.9.3分组

2.9.3.1简单分组聚合

制造数据

df1=pd.DataFrame(
    data=np.random.randint(0,150,size=(10,4)),
    columns=['Python','Java','C++','C']
)
df1['sex']=np.random.randint(0,2,size=10)
df1['sex']=df1['sex'].replace({0:'男',1:'女'})

以性别分组

groups=df1.groupby(by='sex')
for group in groups:
    print(group)

求出各组中指定科目的最小值

groups[['Python','Java','C++','C']].mean()
  • min()
  • max()
  • mean()
  • median()
  • std()
  • count()

求出各组中指定科目最小值和指定科目的最大值

groups.agg({'Python':'max','Java':'min'})

在这里也可以使用其他聚合函数,max,min,mean,std

对数据多次分组并对每个属性进行不同的处理

groups=df1.groupby(by=['sex','grade'])
groups.agg({'Python':'mean','Java':'std'})

2.9.3.2高级分组

我们可以认为是自定义聚合函数,和聚合函数的功能一样的,只不过是自定义的。因为有的时候,需要获取全部的被聚合之后的数据,用到高级聚合也就是自定义聚合的时候,通常会用到transform和apply两个重要的函数,但个人推荐使用apply函数.下面举个例子:

def convert(item):
    cond=item>80
    item=item[cond]
    c=item.count()[0]
    return {'mean':np.round(item.mean()[0],1),'count':c}
# 分组之后,一个组就是一个Series,每次调用apply都映射一个组
df1.groupby(by='grade')[['Python']].apply(convert)

transform和apply的异同点:

transform函数

  • 只允许在同一时间在一个Series上进行一次转换,如果定义列‘a’ 减去列‘b’,  则会出现异常;
  • 必须返回与 group相同的单个维度的序列(行)
  •  返回单个标量对象也可以使用,如 . transform(sum)

apply函数:

  • 不同于transform只允许在Series上进行一次转换, apply对整个DataFrame 作用
  • apply隐式地将group 上所有的列作为自定义函数
     

2.10层次化索引

2.10.1多层索引的创建

显式索引的创建

s=pd.Series(
    data=np.random.randint(0,150,size=4),
    index=pd.MultiIndex.from_product([['关羽','张飞'],['期中','期末']])
)

隐式索引的创建

s=pd.Series(
    data=np.random.randint(0,150,size=4),
    index=pd.MultiIndex.from_tuples(
        [('关羽','期中'),
         ('关羽','期末'),
         ('张飞','期中'),
         ('关羽','期末')]
    )
)

DataFrame层次化索引

df=pd.DataFrame(
    data=np.random.randint(0,150,size=(4,4)),
    index=['python','java','php','mysql'],
    columns=pd.MultiIndex.from_product([['周杰伦','张杰'],['期中','期末']])
)

2.10.2多层索引的索引和切片

2.10.2.1Series多层索引和切片

对于Series来说,直接中括号和.loc[]完全一样,推荐使用括号索引和切片,series进行索引的时候只需要在中括号中使用逗号分割开就可以了.

s=pd.Series(
    data=np.random.randint(0,150,size=10),
    index=pd.MultiIndex.from_product([list('ABCDE'),['期中','期末']])
)
s[:,'期中']  # 获取所有人期中成绩
s[['A','D']]  # 获取A和D的成绩
s['A':'D'][:,'期中']  # 获取A到D的成绩

在Series中,如果我们想要进行切片,我们可以把第一层索引看成行,第二层索引看成列进行切片,如果我们想要进行索引,我们需要用两层中括号括起来,内层括号表示取出每个元素,外层括号表示这些元素对应的列表。

2.10.2.2DataFrame多层索引和切片

df=pd.DataFrame(
    data=np.random.randint(0,150,size=(10,4)),
    index=pd.MultiIndex.from_product([list('ABCDE'),['期中','期末']]),
    columns=['Python','Java','C++','C']
)
df.loc[['B','D']][['Python','Java']]  # 索引
df.loc['B':'D','Python':'C++']  # 切片

2.10.3多层索引行列转换

由外向内分别是0层、1层。

df.unstack(level=0)  # 转换外层索引
df.unstack(level=1)  # 转换内层索引

行列索引的转换我们使用stack函数

df.stack(level=0)

2.10.4多层索引计算

在进行多层索引计算的时候,我们不需要指定axis轴,系统会自动为我们查找哪个轴时多层索引,之不过多了level,我们用来指定它的索引层数。

df.mean(level=0)  # 第一层
df.mean(level=1)  # 第二层
发布了133 篇原创文章 · 获赞 67 · 访问量 9922

猜你喜欢

转载自blog.csdn.net/weixin_43797885/article/details/104539340