python数据分析05--pandas数据清洗、DataFrame级联及合并操作、pandas高级操作

1 Pandas数据清洗

import numpy as np 
import pandas as pd
from pandas import DataFrame,Series

1.1 处理丢失数据

# 2个丢失数据的种类:None、np.nan(NaN)
# None的type是NoneType,np.nan的type是float
两者区别:
	None+1等于1,np.nan+1还是nan
	
如果pandas中使用了None,会被自动转换成NAN

1.2 处理空值操作

# 1.创建一个带空值的df
df = DataFrame(data=np.random.randint(0,100,size=(5,6)))
df.iloc[1,3] = None
df.iloc[2,4] = np.nan
df.iloc[3,2] = None
df

# 2.检测行、列中是否存在空值
df.isnull().any(axis=0)	# 列
df.notnull().all(axis=0)

# 3.计算每一列中存有空值的数量是多少
df.isnull().sum(axis=0)

# 4.删除空对应的行数据
df.notnull().all(axis=1)
df.loc[df.notnull().all(axis=1)]

df.dropna(axis=0)

# 5.空值覆盖,指定值进行覆盖,覆盖不影响原df
df.fillna(value=999)	
# 使用空值近邻值进行填充
df.fillna(method='bfill',axis=0)	# 下面
# 使用空值列对应的均值进行填充
cols = df.columns
for col in cols:
	null_counts = df[col].isnull().sum()	# 那一列的空值数量,用sum计算
	if null_counts > 0:
		mean_value = df[col].mean()		# 均值=那一行的均值
		df[col] = df[col].fillna(value=mean_value)	# 用mean_value填充空值
df

# 使用中位数进行填充
cols = df.columns
for col in cols:
	null_counts = df[col].isnull().sum()
	if null_counts > 0:
		median_value = np.median(df[col][df[col].notnull()])
		df[col] = df[col].fillna(value=median_value)
df
		
data = pd.read_excel('./data/testData.xlsx')
data.drop(labels=['none','none1'],inplace=True,axis=1)
data.head()

data.shape[0]	# 多少行
data.isnull().any(axis=1).sum()		# 有多少行存有空值
data.fillna(method='ffill',axis=0).fillna(method='bfill',axis=0)	# 填充

1.3 重复数据的处理

df.iloc[1] = [1,1,1,1,1,1]
df.iloc[3] = [1,1,1,1,1,1]
df

# 检测是否有重复的数据存在
df.duplicated(keep='last')
# 直接检测+删除重复的行数据
df.drop_duplicates()

1.4 处理异常数据

如:自定义一个1000行3列(A,B,C)取值范围为0-1的数据源,然后将C列中的值大于其两倍标准差的异常值进行清洗

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

# 两倍标准差
twice_std = df['C'].std() * 2
twice_std
# 拿C与两倍标准差的值对比,满足条件的为异常值,清洗就是不要了,所以前面~为取反
df.loc[~(df['C'] > twice_std)]

2 DataFrame级联与合并操作

2.1 级联操作

什么是级联啊?

  • pd.concat
  • pd.append
# 导包
import numpy as np
import pandas as pd
from pandas import DataFrame
df1 = pd.DataFrame(data=np.random.randint(0,100,size=(4,3)),columns=['A','B','C'])
df2 = pd.DataFrame(data=np.random.randint(0,100,size=(4,3)),columns=['A','B','D'])

# 匹配级联
pd.concat((df1,df1),axis=1)		# ABCABC
# 不匹配级联,级联维度的索引不一致,有外连接(补NaN)和内连接(只连接匹配的项)两种方式
pd.concat((df1,df2),axis=0,join='inner')
pandas使用pd.concat函数的参数:

 - objs
 - axis = 0
 - keys
 - join = 'outer' / 'inner'	# 级联方式:outer会将所有的项进行级联(忽略匹配和不匹配),而inner只会将匹配的项级联到一起,不匹配的不级联
 - ignore_index = False		# 忽略索引

2.2 合并操作

merge与concat的区别在于,merge需要依据某一共同列来进行合并。
使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并。
注意每一列元素的顺序不要求一致。

key的规范化:两张表没有可进行连接的列时,可使用left_on和right_on手动指定merge中左右两边哪一列作为连接的列

# 一对一合并
df1 = DataFrame({'employee':['Bob','Jake','Lisa'],
                'group':['Accounting','Engineering','Engineering'],
                })
df2 = DataFrame({'employee':['Lisa','Bob','Jake'],
                'hire_date':[200+4,2008,2012],
                })

pd.merge(left=df1,right=df2,on='employee')	# on为key
pd.merge(left=df1,right=df2)
# 一对多合并,多对多
df3 = DataFrame({
    'employee':['Lisa','Jake'],
    'group':['Accounting','Engineering'],
    'hire_date':[2004,2016]})

df4 = DataFrame({'group':['Accounting','Engineering','Engineering'],
                       'supervisor':['Carly','Guido','Steve']
                })

pd.merge(df3,df4)

df5 = DataFrame({'group':['Engineering','Engineering','HR'],
                'supervisor':['Carly','Guido','Steve']
                })

pd.merge(df1,df5)
pd.merge(left=df1,right=df5,how='right')

3 Pandas的高级操作

3.1 替换操作

替换操作可同步作用在Series和DataFrame中

# 单值替换
普通替换:替换所有符合要求的元素;
to_replace=15,value='e'
按照指定单值替换:
to_replace={列标签:替换值},value='value'

# 多值替换
列表替换:
to_replace=[ ],value=[]
字典替换:
to_replace = {to_replace:value, to_replace:value}

df = DataFrame(data=np.random.randint(0,20,size=(6,7)))
# 将所有的2都替换为two
df.replace(to_replace=2,value='two')
# 将所有的1都替换为one,通过字典格式,推荐
df.replace(to_replace={1:'one'})
# 指定列的替换,将列索引为3的列中的2这个值替换为two
df.replace(to_replace={3:2},value='two')

3.2 映射操作

创建一个映射关系列表,把values元素和一个特定的标签或者字符串绑定,(给一个元素值提供不同的表现形式)

我觉得,映射其实就是一种规则,对原数据进行批量升级的规则。

# 创建一个df,两列分别是姓名和薪资,然后给其名字起对应的英文名

dic = {
	'name':['张三','李四','张三'],
	'salary':[1000,2000,1000]
}
df = DataFrame(dic)

# 映射关系
dic = {
	'张三':'tom',
	'李四':'jerry'
}
df['e_name'] = df['name'].map(dic)	# 将tom值映射给张三
df
# 运算工具map

# 超过500部分的钱缴纳50%的税,计算每个人的税后薪资
def after_sal(s):	# 税后
	return s - (s-500)*0.5
df['after_sal'] = df['salary'].map(after_sal)

# Series的方法apply也可以充当运算工具,而且效率远高于map

3.3 排序实现的随机抽样

take()
np.random.permutation()

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

np.random.permutation(3)
df.take(indices=np.random.permutation(3),axis=1).take(indices=np.random.permutation(100),axis=0)[0:50]

3.4 数据的分类处理

groupby( ) 函数,groups属性查看分组情况

df = DataFrame({'item':['Apple','Banana','Orange','Banana','Orange','Apple'],
                'price':[4,3,3,2.5,4,2],
               'color':['red','yellow','yellow','green','green','green'],
               'weight':[12,20,50,30,20,44]})

# 对水果种类分类
df.groupby(by='item')
# 查看分组结果
df.groupby(by='item').groups
# 查看每一种水果的平均价格
df.groupby(by='item').mean()['price']
mean_price = df.groupby(by='item')['price'].mean()  # 推荐
# 将每一种水果的平均价格汇总到原始数据中
df['mean_price'] = df['item'].map(mean_price.to_dict())
# 计算每一种颜色水果的平均重量,将其汇总到原始局中
df['color'].map(df.groupby(by='color')['weight'].mean().to_dict())

使用groupby分组后,可以使用transform和apply提供自定义函数实现更多的运算,他俩接收函数包括lambda表达式

def my_mean(p):
    sum = 0
    for i in p:
        sum += i
    return sum / len(p)
    
df.groupby(by='item')['price'].transform(my_mean)	# transform里面直接传函数
df.groupby(by='item')['price'].apply(my_mean)		# 一样
# df.apply可以对df中的行或者列进行任意形式的操作
df.apply(myFunc,axis=0)
# applymap可以对df中的每一个元素进行任意形式的操作
data.applymap(ffunc)	# ffunc函数对元素进行了操作

3.5 数据加载

读取操作:.read_csv( )

# 读取
df = pd.read_csv('./data/type.txt')
# 当列索引为第一行内容时,加上header=None,sep是分割
pd.read_csv('./data/type.txt',header=None,sep='-')

# 读取数据库里的数据
# 1.连接数据库,获取连接对象
import sqlite3 as sqlite3
conn = sqlite3.connect('./data/weather_2012.sqlite')
# 2.读取数据库表中的数据值
sql_df = pd.read_sql('select * from weather_2012',conn)
sql_df
# 将一个df中的数据写入存储到db
df.to_sql('dddfff123',conn)

pd.read_sql('select * from dddfff123',conn)

# 输出几行几列
df.shape

3.6 透视表pivot_table

它是一种表格格式,可以对数据进行动态排布且分类汇总

优点:

  1. 灵活,可定制
  2. 脉率清晰
  3. 操作性强

参数:

  1. index:作为分类汇总的条件
  2. values:需要对计算的数据进行筛选
  3. columns:可以设置列层次字段,对values字段进行分类
  4. aggfunc:设置我们对数据聚合时进行的函数操作,如aggfunc=‘mean’
df.pivot_table(index='主客场')
df.pivot_table(index=['主客场','胜负'],values=['得分','篮板','助攻'])
df.pivot_table(index=['主客场','胜负'],values=['得分','篮板','助攻'],aggfunc='sum')

#获取所有队主客场的总得分
df.pivot_table(index='主客场',values='得分',aggfunc='sum')
#查看主客场下的总得分的组成元素是谁
df.pivot_table(index='主客场',values='得分',aggfunc='sum',columns='对手',fill_value=0)
#主流用法:还想获得james harden在主客场和不同胜负情况下的最高得分、平均篮板、总助攻时:
df.pivot_table(index=['主客场','胜负'],aggfunc={'得分':'max','篮板':'mean','助攻':'sum'})

3.7 交叉表crosstab

它是一种特殊透视表,用于计算分组,对数据进行汇总
pd.crosstab(index,columns)

  • index: 分组数据,交叉表的行索引
  • columns: 交叉表的列索引
df = DataFrame({'sex':['man','man','women','women','man','women','man','women','women'],
               'age':[15,23,25,17,35,57,24,31,22],
               'smoke':[True,False,False,True,True,False,False,True,False],
               'height':[168,179,181,166,173,178,188,190,160]})

# 求各个性别抽烟的人数
pd.crosstab(index=df['smoke'],columns=df['sex'])

# 求各个年龄段抽烟人情况
pd.crosstab(index=df['age'],columns=df['smoke'])

你可能感兴趣的:(数据分析)