day09数据分析

day09数据分析

query筛选

abb_pop_area.query('year == 2010 & ages == "total"')

map

apply

transform

删除重复数据

drop_per

删除空置数据

drop

add_per_

删除异常数据

twict = stu()

df.notnull().all(axis=1) #相反的, 组合使用 notnull all

1565685888176

df.loc[df.notnull().all(axis=1)]

1565685876106

过滤df中的空值(只保留没有空值的行)

df.dropna(axis=0) #

1565685907314

效果一样:

df.loc[df.notnull().all(axis=1)]
df.dropna(axis=0)

练习7:

简述None与NaN的区别

假设张三李四参加模拟考试,但张三因为突然想明白人生放弃了英语考试,因此记为None,请据此创建一个DataFrame,命名为ddd3

老师决定根据用数学的分数填充张三的英语成绩,如何实现? 用李四的英语成绩填充张三的英语成绩?

# import random # 不用引入
ddd = DataFrame(data =np.random.randint(90,130,size=(2,2)),index=['英语','数学'],columns=['张三','李四'])
ddd
ddd.loc['数学','张三'] = np.nan
ddd
ddd.fillna(method='ffill',axis=0)
ddd.fillna(method='bfill',axis=1)

张三 李四
英语 93.0 103.0
数学 91.0 91.0

处理丢失数据

有两种丢失数据: None np.nan(NaN)

type(None)---->NoneType

type(np.nan)------>float

np.nan+1------->nan

将某些数组元素赋值为nan

df.iloc[2,4] = None
df.iloc[5,5] = np.nan
df.iloc[2,2] = None
df.iloc[7,3] = None
df.iloc[6,8] = None # 自动转化成nan
df

# pandas 处理空值操作

df.isnull().any(axis=1)# axis =1 是行, drop axis=0 是行

1565691962788

df.notnull().all(axis=1) #相反的, 组合使用 notnull all

1565691974369

df.loc[df.notnull().all(axis=1)]

1565691990666

过滤df中的空值(只保留没有空值的行)

df.dropna(axis=0) #

1565692008733

df.fillna(method='ffill',axis=0)# 列 前 +

1565692021491

2 的拼接操作

1.使用pd.concat()级联

1)匹配级联

pd.concat((df1,df1),axis=1,join='inner')

pd.concat((df1,df1),axis=0,join='inner')

1565694417775

1)非匹配级联

pd.concat((df1,df2),axis=0,join='inner')

1565694406123

2.使用pd.merge()合并

merge与concat的区别在于,merge需要依据某一共同的列来进行合并

使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并。

注意每一列元素的顺序不要求一致

参数:

how:out取并集 inner取交集

on:当有多列相同的时候,可以使用on来指定使用那一列进行合并,on的值为一个列表

1) 一对一合并

df1 = DataFrame({
'employee':['Bob','Jake','Lisa'],
'group':['Accounting','Engineering','Engineering'],
})

df2 = DataFrame({
'employee':['Bob','Jake','Lisa'],
'hire_date':[2004,2008,2012],
})

1565694474193

1565694486930

1565694505369

pd.merge(df1,df2)

  1. 多对一合并

1565694614617

1565694619837

1565694632028

pd.merge(df3,df4)

3) 多对多合并

1565694665411

1565694673154

1565694688283

pd.merge(df5,df6,how='outer')

4) key的规范化

当列冲突时,即有多个列名称相同时,需要使用on=来指定哪一个列作为key,配合suffixes指定冲突列名

1565694717896

1565694724111

1565694738949

pd.merge(df1,df2,on='employee')

5) 内合并与外合并:

out取并集 inner取交集¶

内合并:只保留两者都有的key(默认模式)

外合并 how='outer':补NaN

作业

  1. 案例分析:美国各州人口数据分析¶

1.删除重复元素

使用duplicated()函数检测重复的行,返回元素为布尔类型的Series对象,每个元素对应一行,如果该行不是第一次出现,则元素为True

  • keep参数:指定保留哪一重复的行数据
    创建具有重复元素行的DataFrame

创建一个df

df = DataFrame(data=np.random.randint(0,100,size=(9,5)))
df.iloc[1] = [6,6,6,6,6]
df.iloc[3] = [6,6,6,6,6]
df.iloc[5] = [6,6,6,6,6]
df
  • 使用drop_duplicates()函数删除重复的行
    • drop_duplicates(keep='first/last'/False)

df.drop_duplicates(keep='first')

df.drop_duplicates(keep='last')

1565694916485

2.映射

1) replace()函数:替换元素

DataFrame替换操作

  • 单值替换
    • 普通替换: 替换所有符合要求的元素:to_replace=15,value='e'
    • 按列指定单值替换: to_replace={列标签:替换值} value='value'
  • 多值替换
    • 列表替换: to_replace=[] value=[]
    • 字典替换(推荐) to_replace=

替换一行

df.replace(to_replace=6,value='six')

1565694987077

替换单个值

df.replace(to_replace={4:'four'})

1565694996808

df.replace(to_replace={4:6},value='six') #指定 第四行为6的元素换成six

1565695006423

2)map()函数:

新建一列 , map函数并不是df的方法,而是series的方法-map()函数:新建一列-,---map函数并不是df的方法,而是series的方法)

  • map()可以映射新一列数据
  • map()中可以使用lambd表达式
  • map()中可以使用方法,可以是自定义的方法
eg:map({to_replace:value})
  • 注意 map()中不能使用sum之类的函数,for循环
  • 新增一列:给df中,添加一列,该列的值为中文名对应的英文名

映射

1565695656461

dic = {
'jay':'周杰伦',
'tom':'张三'
}
df['c_name'] = df['name'].map(dic)
df1565695661728

map当做一种运算工具,至于执行何种运算,是由map函数的参数决定的(参数:lambda,函数)

  • 使用自定义函数

def after_sal(s):
return s- (s-5000)*0.5

超过5000部分的钱缴纳50%的税

df['after_sal'] = df['salary'].map(after_sal)

1565695727072

apply()函数

也可以运算

df['salary'].apply(after_sal)#返回的是索引

1565695739576

注意:并不是任何形式的函数都可以作为map的参数。只有当一个函数具有一个参数且有返回值,那么该函数才可以作为map的参数。

3.使用聚合操作对数据异常值检测和过滤

使用df.std()函数可以求得DataFrame对象每一列的标准差

  • 创建一个1000行3列的df 范围(0-1),求其每一列的标准差

df = DataFrame(data=np.random.random(size=(1000,3)),columns=['A','B','C'])
df.head()
df

对df应用筛选条件,去除标准差太大的数据:假设过滤条件为 C列数据大于两倍的C列标准差

std_twice = df['C'].std() * 2
std_twice

df['C']>std_twice

异常值对应的行数据

df.loc[df['C']>std_twice]
indexs = df.loc[df['C']>std_twice].index
df.drop(labels=indexs, axis=0, inplace=True)
df

  • 数据清洗
    • 清洗空值
      • dropna fillna isnull notnull any all
    • 清洗重复值
      • drop_duplicates(keep)
    • 清洗异常值
      • 异常值监测的结果(布尔值),作为清洗的过滤的条件

4. 排序

使用.take()函数排序
- take()函数接受一个索引列表,用数字表示,使得df根据列表中索引的顺序进行排序
- eg:df.take([1,3,4,2,5])

可以借助np.random.permutation()函数随机排序

df.take([2,1,0],axis=1)# 隐性索引的 为了方便自动生成?

df.take([2,1,0],axis=1).take(np.random.permutation(500),axis=0)#随机排序

随机取20行

df.take([2,1,0],axis=1).take(np.random.permutation(500),axis=0)[0:20]

  • np.random.permutation(x)可以生成x个从0-(x-1)的随机数列
随机抽样

当DataFrame规模足够大时,直接使用np.random.permutation(x)函数,就配合take()函数实现随机抽样

5. 数据分类处理【重点】

数据聚合是数据处理的最后一步,通常是要使每一个数组生成一个单一的数值。

数据分类处理:

  • 分组:先把数据分为几组
  • 用函数处理:为不同组的数据应用不同的函数以转换数据
  • 合并:把不同组得到的结果合并起来

数据分类处理的核心:

  • groupby()函数
    groups属性查看分组情况
    • eg: df.groupby(by='item').groups
分组

1565695980367

  • 使用groupby实现分组
df.groupby(by='item')
<pandas.core.groupby.DataFrameGroupBy object at 0x000000000E3D5BA8>
  • 使用groups查看分组情况

  • 该函数可以进行数据的分组, 但是不显示分组情况

    df.groupby(by='item').groups

{'Apple': Int64Index([0, 5], dtype='int64'),
 'Banana': Int64Index([1, 3], dtype='int64'),
 'Orange': Int64Index([2, 4], dtype='int64')}

给df创建一个新列, 内容为各个水果的平均价格

df.groupby(by='item').mean()['price'] # 增加记算量,不提倡

1565696050510

mean_price = df.groupby(by='item')['price'].mean()

dic = mean_price.to_dict()
dic

{'Apple': 3.0, 'Banana': 2.75, 'Orange': 3.5}

df['mean_price'] = df['item'].map(dic) # 加到表中
df

1565696077882

计算出苹果的平均价格
按颜色查看各种颜色的水果的平均价格
汇总:将各种颜色水果的平均价格和df进行汇总

df[df['item']=='Apple']['price'].mean()

df.groupby(by='color')['price'].mean().to_dict()

df['color_price'] = df['color'].map(df.groupby(by='color')['price'].mean().to_dict())
df

1565696108336

6.0 高级数据聚合

使用groupby分组后,也可以使用transform和apply提供自定义函数实现更多的运算

  • df.groupby('item')['price'].sum() <==> df.groupby('item')['price'].apply(sum)
  • transform和apply都会进行运算,在transform或者apply中传入函数即可
  • transform和apply也可以传入一个lambda表达式

def my_mean(s):
print(s) # Name: Apple, dtype: float64
sum = 0
for i in s:
sum+=i
return sum/s.size

df.groupby(by='item')['price'].transform(my_mean)# 返回的是索引 自定义平均价格

返回的是一个个的[苹果s],[香蕉s],[西瓜s]

df.groupby(by='item')['price'].apply(my_mean)

1565696172330

posted @ 2019-08-13 22:58  learnacode  阅读(175)  评论(0编辑  收藏  举报