pandas数据分析库
第七部分 数据清洗
- import numpy as np
- import pandas as pd
- df = pd.DataFrame(data = {'color':['red','blue','red','green','blue',None,'red'],
- 'price':[10,20,10,15,20,0,np.NaN]})
- # 1、重复数据过滤
- df.duplicated() # 判断是否存在重复数据
- df.drop_duplicates() # 删除重复数据
- # 2、空数据过滤
- df.isnull() # 判断是否存在空数据,存在返回True,否则返回False
- df.dropna(how = 'any') # 删除空数据
- df.fillna(value=1111) # 填充空数据
- # 3、指定行或者列过滤
- del df['color'] # 直接删除某列
- df.drop(labels = ['price'],axis = 1)# 删除指定列
- df.drop(labels = [0,1,5],axis = 0) # 删除指定行
- # 4、函数filter使用
- df = pd.DataFrame(np.array(([3,7,1], [2, 8, 256])),
- index=['dog', 'cat'],
- columns=['China', 'America', 'France'])
- df.filter(items=['China', 'France'])
- # 根据正则表达式删选列标签
- df.filter(regex='a$', axis=1)
- # 选择行中包含og
- df.filter(like='og', axis=0)
- # 5、异常值过滤
- df2 = pd.DataFrame(data = np.random.randn(10000,3)) # 正态分布数据
- # 3σ过滤异常值,σ即是标准差
- cond = (df2 > 3*df2.std()).any(axis = 1)
- index = df2[cond].index # 不满足条件的行索引
- df2.drop(labels=index,axis = 0) # 根据行索引,进行数据删除
复制代码 第八部分 数据转换
第一节 轴和元素替换
- import numpy as np
- import pandas as pd
- df = pd.DataFrame(data = np.random.randint(0,10,size = (10,3)),
- index = list('ABCDEFHIJK'),
- columns=['Python','Tensorflow','Keras'])
- df.iloc[4,2] = None # 空数据
- #1、重命名轴索引
- df.rename(index = {'A':'AA','B':'BB'},columns = {'Python':'人工智能'})
- # 2、替换值
- df.replace(3,1024) #将3替换为1024
- df.replace([0,7],2048) # 将0和7替换为2048
- df.replace({0:512,np.nan:998}) # 根据字典键值对进行替换
- df.replace({'Python':2},-1024) # 将Python这一列中等于2的,替换为-1024
复制代码 第二节 map Series元素改变
- import numpy as np
- import pandas as pd
- df = pd.DataFrame(data = np.random.randint(0,10,size = (10,3)),
- index = list('ABCDEFHIJK'),
- columns=['Python','Tensorflow','Keras'])
- df.iloc[4,2] = None # 空数据
- # 1、map批量元素改变,Series专有
- df['Keras'].map({1:'Hello',5:'World',7:'AI'}) # 字典映射
- df['Python'].map(lambda x:True if x >=5 else False) # 隐式函数映射
- def convert(x): # 显示函数映射
- if x%3 == 0:
- return True
- elif x%3 == 1:
- return False
- df['Tensorflow'].map(convert)
复制代码 第三节 apply元素改变。既支持 Series,也支持 DataFrame
- import numpy as np
- import pandas as pd
- df = pd.DataFrame(data = np.random.randint(0,10,size = (10,3)),
- index = list('ABCDEFHIJK'),
- columns=['Python','Tensorflow','Keras'])
- df.iloc[4,2] = None # 空数据
- # 1、apply 应用方法数据转换,通用
- # Series,其中x是Series中元素
- df['Keras'].apply(lambda x:True if x >5 else False)
- # DataFrame,其中的x是DataFrame中列或者行,是Series
- df.apply(lambda x : x.median(),axis = 0) # 列的中位数
- def convert(x): # 自定义方法
- return (x.mean().round(1),x.count())
- df.apply(convert,axis = 1) # 行平均值,计数
- # 2、applymap DataFrame专有
- df.applymap(lambda x : x + 100) # 计算DataFrame中每个元素
复制代码 第四节 transform变形金刚
- import numpy as np
- import pandas as pd
- df = pd.DataFrame(data = np.random.randint(0,10,size = (10,3)),
- index = list('ABCDEFHIJK'),
- columns=['Python','Tensorflow','Keras'])
- df.iloc[4,2] = None # 空数据
- # 1、一列执行多项计算
- df['Python'].transform([np.sqrt,np.exp]) # Series处理
- def convert(x):
- if x.mean() > 5:
- x *= 10
- else:
- x *= -10
- return x
- # 2、多列执行不同计算
- df.transform({'Python':convert,'Tensorflow':np.max,'Keras':np.min}) # DataFrame处理
复制代码 第五节 重排随机抽样哑变量
- import numpy as np
- import pandas as pd
- df = pd.DataFrame(data = np.random.randint(0,10,size = (10,3)),
- index = list('ABCDEFHIJK'),
- columns=['Python','Tensorflow','Keras'])
- ran = np.random.permutation(10) # 随机重排
- df.take(ran) # 重排DataFrame
- df.take(np.random.randint(0,10,size = 15)) # 随机抽样
- # 哑变量,独热编码,1表示有,0表示没有
- df = pd.DataFrame({'key':['b','b','a','c','a','b']})
- pd.get_dummies(df,prefix='',prefix_sep='')
复制代码 第九部分 数据重塑
- import numpy as np
- import pandas as pd
- df = pd.DataFrame(data = np.random.randint(0,100,size = (10,3)),
- index = list('ABCDEFHIJK'),
- columns=['Python','Tensorflow','Keras'])
- df.T # 转置
- df2 = pd.DataFrame(data = np.random.randint(0,100,size = (20,3)),
- index = pd.MultiIndex.from_product([list('ABCDEFHIJK'),['期中','期末']]),#多层索引
- columns=['Python','Tensorflow','Keras'])
- df2.unstack(level = -1) # 行旋转成列,level指定哪一层,进行变换
- df2.stack() # 列旋转成行
- df2.stack().unstack(level = 1) # 行列互换
- # 多层索引DataFrame数学计算
- df2.mean() # 各学科平均分
- df2.mean(level=0) # 各学科,每个人期中期末平均分
- df2.mean(level = 1) # 各学科,期中期末所有人平均分
复制代码 第十部分 数学和统计方法
pandas对象拥有一组常用的数学和统计方法。它们属于汇总统计,对Series汇总计算获取mean、max值大概对DataFrame行、列汇总计算返回一个Series。
第一节 简单统计指标
- import numpy as np
- import pandas as pd
- df = pd.DataFrame(data = np.random.randint(0,100,size = (20,3)),
- index = list('ABCDEFHIJKLMNOPQRSTU'),
- columns=['Python','Tensorflow','Keras'])
- # 1、简单统计指标
- df.count() # 非NA值的数量
- df.max(axis = 0) #轴0最大值,即每一列最大值
- df.min() #默认计算轴0最小值
- df.median() # 中位数
- df.sum() # 求和
- df.mean(axis = 1) #轴1平均值,即每一行的平均值
- df.quantile(q = [0.2,0.4,0.8]) # 分位数
- df.describe() # 查看数值型列的汇总统计,计数、平均值、标准差、最小值、四分位数、最大值
复制代码 第二节 索引标签、位置获取
- # 2、索引位置
- df['Python'].argmin() # 计算最小值位置
- df['Keras'].argmax() # 最大值位置
- df.idxmax() # 最大值索引标签
- df.idxmin() # 最小值索引标签
复制代码 第三节 更多统计指标
- # 3、更多统计指标
- df['Python'].value_counts() # 统计元素出现次数
- df['Keras'].unique() # 去重
- df.cumsum() # 累加
- df.cumprod() # 累乘
- df.std() # 标准差
- df.var() # 方差
- df.cummin() # 累计最小值
- df.cummax() # 累计最大值
- df.diff() # 计算差分
- df.pct_change() # 计算百分比变化
复制代码 第四节 高级统计指标
- # 4、高级统计指标
- df.cov() # 属性的协方差
- df['Python'].cov(df['Keras']) # Python和Keras的协方差
- df.corr() # 所有属性相关性系数
- df.corrwith(df['Tensorflow']) # 单一属性相关性系数
复制代码 协方差: C o v ( X , Y ) = ∑ 1 n ( X i − X ‾ ) ( Y i − Y ‾ ) n − 1 Cov(X,Y) = \frac{\sum\limits_1^n(X_i - \overline{X})(Y_i - \overline{Y})}{n-1} Cov(X,Y)=n−11∑n(Xi−X)(Yi−Y)
相关性系数: r ( X , Y ) = C o v ( X , Y ) V a r [ X ] V a r [ Y ] r(X,Y) = \frac{Cov(X,Y)}{\sqrt{Var[X]Var[Y]}} r(X,Y)=Var[X]Var[Y] Cov(X,Y)
第十一部分 数据排序
- import numpy as np
- import pandas as pd
- df = pd.DataFrame(data = np.random.randint(0,30,size = (30,3)),
- index = list('qwertyuioijhgfcasdcvbnerfghjcf'),
- columns = ['Python','Keras','Pytorch'])
- # 1、索引列名排序
- df.sort_index(axis = 0,ascending=True) # 按索引排序,降序
- df.sort_index(axis = 1,ascending=False) #按列名排序,升序
- # 2、属性值排序
- df.sort_values(by = ['Python']) #按Python属性值排序
- df.sort_values(by = ['Python','Keras'])#先按Python,再按Keras排序
- # 3、返回属性n大或者n小的值
- df.nlargest(10,columns='Keras') # 根据属性Keras排序,返回最大10个数据
- df.nsmallest(5,columns='Python') # 根据属性Python排序,返回最小5个数据
复制代码 第十二部分 分箱操纵
分箱操纵就是将连续数据转换为分类对应物的过程。比如将连续的身高数据分别为:矮中高。
分箱操纵分为等距分箱和等频分箱。
分箱操纵也叫面元分别大概离散化。
- import numpy as np
- import pandas as pd
- df = pd.DataFrame(data = np.random.randint(0,150,size = (100,3)),
- columns=['Python','Tensorflow','Keras'])
- # 1、等宽分箱
- pd.cut(df.Python,bins = 3)
- # 指定宽度分箱
- pd.cut(df.Keras,#分箱数据
- bins = [0,60,90,120,150],#分箱断点
- right = False,# 左闭右开
- labels=['不及格','中等','良好','优秀'])# 分箱后分类
- # 2、等频分箱
- pd.qcut(df.Python,q = 4,# 4等分
- labels=['差','中','良','优']) # 分箱后分类
复制代码 第十三部分 分组聚合
第一节 分组
- import numpy as np
- import pandas as pd
- # 准备数据
- df = pd.DataFrame(data = {'sex':np.random.randint(0,2,size = 300), # 0男,1女
- 'class':np.random.randint(1,9,size = 300),#1~8八个班
- 'Python':np.random.randint(0,151,size = 300),#Python成绩
- 'Keras':np.random.randint(0,151,size =300),#Keras成绩
- 'Tensorflow':np.random.randint(0,151,size=300),
- 'Java':np.random.randint(0,151,size = 300),
- 'C++':np.random.randint(0,151,size = 300)})
- df['sex'] = df['sex'].map({0:'男',1:'女'}) # 将0,1映射成男女
- # 1、分组->可迭代对象
- # 1.1 先分组再获取数据
- g = df.groupby(by = 'sex')[['Python','Java']] # 单分组
- for name,data in g:
- print('组名:',name)
- print('数据:',data)
- df.groupby(by = ['class','sex'])[['Python']] # 多分组
- # 1.2 对一列值进行分组
- df['Python'].groupby(df['class']) # 单分组
- df['Keras'].groupby([df['class'],df['sex']]) # 多分组
- # 1.3 按数据类型分组
- df.groupby(df.dtypes,axis = 1)
- # 1.4 通过字典进行分组
- m = {'sex':'category','class':'category','Python':'IT','Keras':'IT','Tensorflow':'IT','Java':'IT','C++':'IT'}
- for name,data in df.groupby(m,axis = 1):
- print('组名',name)
- print('数据',data)
复制代码 第二节 分组聚合
- # 2、分组直接调用函数进行聚合
- # 按照性别分组,其他列均值聚合
- df.groupby(by = 'sex').mean().round(1) # 保留1位小数
- # 按照班级和性别进行分组,Python、Keras的最大值聚合
- df.groupby(by = ['class','sex'])[['Python','Keras']].max()
- # 按照班级和性别进行分组,计数聚合。统计每个班,男女人数
- df.groupby(by = ['class','sex']).size()
- # 基本描述性统计聚合
- df.groupby(by = ['class','sex']).describe()
复制代码 第三节 分组聚合apply、transform
- # 3、分组后调用apply,transform封装单一函数计算
- # 返回分组结果
- df.groupby(by = ['class','sex'])[['Python','Keras']].apply(np.mean).round(1)
- def normalization(x):
- return (x - x.min())/(x.max() - x.min()) # 最大值最小值归一化
- # 返回全数据,返回DataFrame.shape和原DataFrame.shape一样。
- df.groupby(by = ['class','sex'])[['Python','Tensorflow']].transform(normalization).round(3)
复制代码 第四节 分组聚合agg
- # 4、agg 多中统计汇总操作
- # 分组后调用agg应用多种统计汇总
- df.groupby(by = ['class','sex'])[['Tensorflow','Keras']].agg([np.max,np.min,pd.Series.count])
- # 分组后不同属性应用多种不同统计汇总
- df.groupby(by = ['class','sex'])[['Python','Keras']].agg({'Python':[('最大值',np.max),('最小值',np.min)],
- 'Keras':[('计数',pd.Series.count),('中位数',np.median)]})
复制代码 第五节 透视表pivot_table
- # 5、透视表
- # 透视表也是一种分组聚合运算
- def count(x):
- return len(x)
- df.pivot_table(values=['Python','Keras','Tensorflow'],# 要透视分组的值
- index=['class','sex'], # 分组透视指标
- aggfunc={'Python':[('最大值',np.max)], # 聚合运算
- 'Keras':[('最小值',np.min),('中位数',np.median)],
- 'Tensorflow':[('最小值',np.min),('平均值',np.mean),('计数',count)]})
复制代码 第十四部分 时间序列
第一节 时间戳操纵
- # 1、创建方法
- pd.Timestamp('2020-8-24 12')# 时刻数据
- pd.Period('2020-8-24',freq = 'M') # 时期数据
- index = pd.date_range('2020.08.24',periods=5,freq = 'M') # 批量时刻数据
- pd.period_range('2020.08.24',periods=5,freq='M') # 批量时期数据
- ts = pd.Series(np.random.randint(0,10,size = 5),index = index) # 时间戳索引Series
- # 2、转换方法
- pd.to_datetime(['2020.08.24','2020-08-24','24/08/2020','2020/8/24'])
- pd.to_datetime([1598582232],unit='s')
- dt = pd.to_datetime([1598582420401],unit = 'ms') # 世界标准时间
- dt + pd.DateOffset(hours = 8) # 东八区时间
- dt + pd.DateOffset(days = 100) # 100天后日期
复制代码 第二节 时间戳索引
- index = pd.date_range("2020-8-24", periods=200, freq="D")
- ts = pd.Series(range(len(index)), index=index)
- # str类型索引
- ts['2020-08-30'] # 日期访问数据
- ts['2020-08-24':'2020-09-3'] # 日期切片
- ts['2020-08'] # 传入年月
- ts['2020'] # 传入年
- # 时间戳索引
- ts[pd.Timestamp('2020-08-30')]
- ts[pd.Timestamp('2020-08-24'):pd.Timestamp('2020-08-30')] # 切片
- ts[pd.date_range('2020-08-24',periods=10,freq='D')]
- # 时间戳索引属性
- ts.index.year # 获取年
- ts.index.dayofweek # 获取星期几
- ts.index.weekofyear # 一年中第几个星期几
复制代码 第三节 时间序列常用方法
在做时间序列相关的工作时,经常要对时间做一些移动/滞后、频率转换、采样等相关操纵,我们来看下这些操纵如何使用
- index = pd.date_range('8/1/2020', periods=365, freq='D')
- ts = pd.Series(np.random.randint(0, 500, len(index)), index=index)
- # 1、移动
- ts.shift(periods = 2) # 数据后移
- ts.shift(periods = -2) # 数据前移
- # 日期移动
- ts.shift(periods = 2,freq = pd.tseries.offsets.Day()) # 天移动
- ts.tshift(periods = 1,freq = pd.tseries.offsets.MonthOffset()) #月移动
- # 2、频率转换
- ts.asfreq(pd.tseries.offsets.Week()) # 天变周
- ts.asfreq(pd.tseries.offsets.MonthEnd()) # 天变月
- ts.asfreq(pd.tseries.offsets.Hour(),fill_value = 0) #天变小时,又少变多,fill_value为填充值
- # 3、重采样
- # resample 表示根据日期维度进行数据聚合,可以按照分钟、小时、工作日、周、月、年等来作为日期维度
- ts.resample('2W').sum() # 以2周为单位进行汇总
- ts.resample('3M').sum().cumsum() # 以季度为单位进行汇总
- # 4、DataFrame重采样
- d = dict({'price': [10, 11, 9, 13, 14, 18, 17, 19],
- 'volume': [50, 60, 40, 100, 50, 100, 40, 50],
- 'week_starting':pd.date_range('24/08/2020',periods=8,freq='W')})
- df1 = pd.DataFrame(d)
- df1.resample('M',on = 'week_starting').apply(np.sum)
- df1.resample('M',on = 'week_starting').agg({'price':np.mean,'volume':np.sum})
- days = pd.date_range('1/8/2020', periods=4, freq='D')
- data2 = dict({'price': [10, 11, 9, 13, 14, 18, 17, 19],
- 'volume': [50, 60, 40, 100, 50, 100, 40, 50]})
- df2 = pd.DataFrame(data2,
- index=pd.MultiIndex.from_product([days,['morning','afternoon']]))
- df2.resample('D', level=0).sum()
复制代码 第四节 时区表现
- index = pd.date_range('8/1/2012 00:00', periods=5, freq='D')
- ts = pd.Series(np.random.randn(len(index)), index)
- import pytz
- pytz.common_timezones # 常用时区
- # 时区表示
- ts = ts.tz_localize(tz='UTC')
- # 转换成其它时区
- ts.tz_convert(tz = 'Asia/Shanghai')
复制代码 第十五部分 数据可视化
pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple
- import numpy as np
- import pandas as pd
- # 1、线形图
- df1 = pd.DataFrame(data = np.random.randn(1000,4),
- index = pd.date_range(start = '27/6/2012',periods=1000),
- columns=list('ABCD'))
- df1.cumsum().plot()
- # 2、条形图
- df2 = pd.DataFrame(data = np.random.rand(10,4),
- columns = list('ABCD'))
- df2.plot.bar(stacked = True) # stacked 是否堆叠
- # 3、饼图
- df3 = pd.DataFrame(data = np.random.rand(4,2),
- index = list('ABCD'),
- columns=['One','Two'])
- df3.plot.pie(subplots = True,figsize = (8,8))
- # 4、散点图
- df4 = pd.DataFrame(np.random.rand(50, 4), columns=list('ABCD'))
- df4.plot.scatter(x='A', y='B') # A和B关系绘制
- # 在一张图中绘制AC散点图,同时绘制BD散点图
- ax = df4.plot.scatter(x='A', y='C', color='DarkBlue', label='Group 1');
- df4.plot.scatter(x='B', y='D', color='DarkGreen', label='Group 2', ax=ax)
- # 气泡图,散点有大小之分
- df4.plot.scatter(x='A',y='B',s = df4['C']*200)
- # 5、面积图
- df5 = pd.DataFrame(data = np.random.rand(10, 4),
- columns=list('ABCD'))
- df5.plot.area(stacked = True);# stacked 是否堆叠
- # 6、箱式图
- df6 = pd.DataFrame(data = np.random.rand(10, 5),
- columns=list('ABCDE'))
- df6.plot.box()
- # 7、直方图
- df7 = pd.DataFrame({'A': np.random.randn(1000) + 1, 'B': np.random.randn(1000),
- 'C': np.random.randn(1000) - 1})
- df7.plot.hist(alpha=0.5) #带透明度直方图
- df7.plot.hist(stacked = True)# 堆叠图
- df7.hist(figsize = (8,8)) # 子视图绘制
复制代码 第十六部分 实战-数据分析师雇用数据分析
第一节 分析目的
- 各城市对数据分析岗位的需求环境
- 差别细分范畴对数据分析岗的需求环境
- 数据分析岗位的薪资状态
- 工作经验与薪水的关系
- 公司都要求什么掌握什么技能
- 岗位的学历要求高吗
- 差别规模的企业对工资经验的要求以及提供的薪资程度
第二节 数据加载
- import pandas as pd
- import numpy as np
- job = pd.read_csv('./job.csv')
- job.drop_duplicates(inplace = True) # 删除重复数据
复制代码 第三节 数据清洗
- 过滤非数据分析的岗位
- # 数据分析相应的岗位数量
- cond = job["positionName"].str.contains("数据分析") # 职位名中含有数据分析字眼的
- # 筛选出我们想要的字段,并剔除positionName
- job = job[cond]
- job.reset_index(inplace=True) # 行索引 重置
- job
复制代码 - 数据中的薪水是一个区间,这里用薪水区间的均值作为相应职位的薪水
- # 处理过程
- #1、将salary中的字符串均小写化(因为存在8k-16k和8K-16K)
- #2、运用正则表达式提取出薪资区间
- #3、将提取出来的数字转化为int型
- #4、取区间的平均值
- job["salary"] = job["salary"].str.lower()\
- .str.extract(r'(\d+)[k]-(\d+)k')\
- .applymap(lambda x:int(x))\
- .mean(axis=1)
复制代码 - 从job_detail中提取出技能要求 将技能分为以下几类
Python
SQL
Tableau
Excel
SPSS/SAS
处理方式: 假如job_detail中含有上述五类,则赋值为1,不含有则为0
- job["job_detail"] = job["job_detail"].str.lower().fillna("") #将字符串小写化,并将缺失值赋值为空字符串
- job["Python"] = job["job_detail"].map(lambda x:1 if ('python' in x) else 0)
- job["SQL"] = job["job_detail"].map(lambda x:1 if ('sql' in x) or ('hive' in x) else 0)
- job["Tableau"] = job["job_detail"].map(lambda x:1 if 'tableau' in x else 0)
- job["Excel"] = job["job_detail"].map(lambda x:1 if 'excel' in x else 0)
- job['SPSS/SAS'] = job['job_detail'].map(lambda x:1 if ('spss' in x) or ('sas' in x) else 0)
复制代码- 处理行业信息
在行业信息中有多个标签,对其举行处理,筛选最显著的行业标签。
- def clean_industry(industry):
- industry = industry.split(",")
- if industry[0]=="移动互联网" and len(industry)>1:
- return industry[1]
- else:
- return industry[0]
- job["industryField"] = job.industryField.map(clean_industry)
复制代码 - 数据分析师职位的数据预处理基本完成,后续使用matplotlib举行数据可视化分析。
pandas库的亮点
- 一个快速、高效的DataFrame对象,用于数据操纵和综合索引;
- 用于在内存数据布局和差别格式之间读写数据的工具:CSV和文本文件、Microsoft Excel、SQL数据库和快速HDF 5格式;
- 智能数据对齐和丢失数据的综合处理:在计算中获得基于标签的自动对齐,并轻松地将缭乱的数据操纵为有序的形式;
- 数据集的机动调整和旋转;
- 基于智能标签的切片、花式索引和大型数据集的子集;
- 可以从数据布局中插入和删除列,以实现巨细可变;
- 通过在强大的引擎中聚合或转换数据,允许对数据集举行拆分应用组合操纵;
- 数据集的高性能合并和毗连;
- 层次轴索引提供了在低维数据布局中处理高维数据的直观方法;
- 时间序列-功能:日期范围生成和频率转换、移动窗口统计、移动窗口线性回归、日期转换和滞后。甚至在不丢失数据的环境下创建特定范畴的时间偏移和加入时间序列;
- 对性能举行了高度优化,用Cython或C编写了关键代码路径。
- Python与pandas在广泛的学术和贸易范畴中使用,包括金融,神经科学,经济学,统计学,广告,网络分析等等
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |