【pyhton】【数据分析】pandas的基础使用
写在最前,现在是周三下午16:11, 一本python书 里边大约有50页pandas使用的讲解 前边两个小时,已经看过了大约25页,预计今天晚上 我能把后边25页看完一遍。准备周五写一篇学习心得。这里利用休息间隔写个准备提纲
# 环境准备 ,python3 使用anaconda 安装 ,---ok了
# 数据准备 , 需要手工准备 一些csv表格
# pandas 函数资料, 明天早上,先把所有的函数 和基本语句
# 案例准备 , 利用书上的思路, 后续可以通过其他书籍的翻阅或者 网络 搜索一下看看 ,
# 关键问题准备 ,先写在这里
1,pandas 如何与 文件 , mysql数据库, list 等不同形式的数据集 进行转换? 还有 ,采用哪种方式,保证数据留存落地
2,pandas如何 实现 mysql 中 sql语句的 增删改 ,以及 group sum avg ,连接 ,order,distinct 这些功能
3,行列转换 如何使用? 对于现有平台运维 能够有些用法
4,重复值, 异常值,空值 如何 处理 ?
5,都说python 效率 不理想 。pandas数据处理 是否 有办法通过多线程 来进行弥补?
to be continued 。。。。。。
=====================================================================================================
正文 第一部分 如下 :
# *-* coding:utf-8 *-*
# python 3
# allen 20190109--0111
# 练习pandas
import pandas as pd
df=pd.read_csv('E:/python/python_test/pandas/data/pandas_data/taobao_data.csv')
df
#行的选取
rows=df[0:3]
rows
#列的选取
cols=df[['宝贝','价格']]
cols.head()
# 选取块
df.loc[0:3,['宝贝','价格']]
# 这里经过提示 ix 改用loc
#操作行和块
df['销售额']=df['价格']*df['成交量']
df.head()
#5 条件过滤
df[(df['价格']<100) & (df['成交量']>1000)]
# 类似 sql中的 where and
## 数据整理
# sed_index 好比 按照 某一列进行排列
df1=df.sed_index("位置")
df1=df1.sort_index()
df1.head()
# 多列排序
df2=df.sed_index("位置","卖家").sort_level(0)
df2.head()
# groub by 求 sum 和 avg
df_mean=df.drop(["商品","卖家"],axis=1).grouby("位置").mean().sort_values("成交量",ascdenging=False)
df_mean=df.drop(["商品","卖家"],axis=1).grouby("位置").sum().sort_values("成交量",ascdenging=False)
df_mean()
df_false()
#df.info()
df.info()
df.describe()
# 可以看作是 show create (or desc)table 和 table 的统计信息
#至此, select where ,and,group by, sum avg ,order by包括 delete 都是已经实现的 ,后边看看
# insert,update 应该如何实现
# 9.2 数据分组, 分割 合并,变形
# 9.2.1,数据分组
grouped=df['成交量'].groupby(df['位置'])
grouped.mean()
# 这里和之前的方式有点区别, 成交量作为数据内容, 位置 作为参考因素, 不管其他数据项,直接只看关注的
# 两个数据项目 ,第一加工 第二部显示
#means=df['成交量'].groupby(df['位置'],df['卖家']).mean()
#means
#正确的是
means=df['成交量'].groupby([df['位置'],df['卖家']]).mean()
means
# 简单来说 groupby 后边 不能跟两个df, 而是可以配合1个 2维的df
# 前边两个例子 分别是 一个数据对应一个条件,以及一个数据对应两个条件
# 下边这个是 多个数据对应一个条件
df.groupby('宝贝').mean()
df.groupby('位置').mean()
# 可见 位置 和 宝贝,属于描述性的数据, 自身没有大小之分,可能有顺序之分,
# 而 成交量 价格 属于数值数据,分大小 且精度高 可以看作是连续的
# 多个数据对应 两个条件
df.grouby(['位置','卖家']).mean()
# 小结说明 , pandas df的语法思路是这样的,
# 确定 数据的 行和列
#先确定对一两个还是所有数子数据进行 运算
# 之后,在 groupby 里边写明条件 ,这里一定是个一个 df, 可以是二维,或者多维
# mean(), sum(),里边不能写条件
# 这个东西以后要搜索一个手册的
# size 类似于 count
df.groupby('位置').size()
df.groupby('卖家').size()
# 前边说了,如果多个条件进行复合的运算,必须用 一个多维的df
df.groupby(['位置','卖家']).size()
# 9.2.2 数据分割
# 数据分割
df1=df[30:40][['位置','卖家','宝贝']]
df1
df2=df[50:60][['卖家','宝贝','价格']]
df2
#df_a=df1[['宝贝','价格']] # 这个因为没有价格,所以会报错
df_a=df1['卖家']
df_a
# 9.2.3 数据合并
#df3=pd.merge(df1,df2,how='outer',on='卖家')
df3=pd.merge(df1,df2,how='right',on='卖家')
df3
# merge说明, how 默认采用 inner 连接方式,也就是全匹配
# on 就是 a b 两个表的主键 条件 , 好了 sql中表连接 也能够实现了,而且看起来语法上简洁很多
# 索引上的合并
df11=df[30:40][['卖家','宝贝','价格']]
df11
df_1=pd.merge(df1,df11,left_index=True,right_index=True)
#df_1=df1.join(df11) # 书上的这个东西 没有实现 ???为什么
df_1
# 上边取了 30:40 行 不同的几个col, 通过卖家进行合并
# ValueError: columns overlap but no suffix specified: Index(['卖家', '宝贝'], dty pe='object')
# 报错以后再研究了
# 轴向连接
# 至少保证 行或者列有一个方面 是可以完全对应的
s1=df[:5]
s2=df[5:10]
s3=df[10:15]
pd.concat([s1,s2,s3])
# 这个当然没有问题, 最终是 0--14行 全col数据集合在一起
#
s1=df[:5]['宝贝']
s2=df[:5]['价格']
s3=df[:5]['成交量']
s4=df[5:10]['成交量']
pd.concat([s1,s2,s3],axis=1)
# axis=1 就是 将表通过纵向轴 进行连接联合
pd.concat([s1,s2,s3]) # 这种不添加参数 就难看很多了,
# 如果行数选取不同
#pd.concat([s1,s2,s4]) # 同样不好看
# 小结一下 ,相当于concat这种简单的续接, merge是相对严格的检查之后的合并, combine_first 书中没有细说
# 9.2.4 数据变形
# 这里换用 天气表格
import pandas as pd
df=pd.read_csv('E:/python/python_test/pandas/data/pandas_data/hz_weather.csv')
df.head()
# 层次化
df.stack().unstack()
# 转成series 转再 转化成 DF
df=df.set_index('日期')
df
#相当于原来的默认 index 去掉,改用日期作为index
df1=pd.pivot_table(df,values=['最高气温'],index=['天气'],columns=['风向'])
df1
# 原来表中 最高气温知识其中一项,现在 是把 风向和 天气 作为参考项目, 作为两个维度标准, 对最高气温进行分析
# 也就是 交叉分类, 目的就是出现null 或者NA 空值 ? 当然不止了
df1.info()
# 9.2.5 旅游数据分析和变形
import pandas as pd
df=pd.read_csv('E:/python/python_test/pandas/data/pandas_data/qunar_free_trip.csv')
df.head()
df1=df['价格'].groupby([df['出发地'],df['目的地']]).mean()
df1
#学过的,这里用一下
df_=pd.read_csv('E:/python/python_test/pandas/data/pandas_data/qunar_route_cnt.csv')
df_.head()
# 综合运用一下
df1=df.groupby([df['出发地'],df['目的地']],as_index=False).mean()
df1
# 按照出发地和目的 取一下平均值
pd.merge(df1,df_).head(10)
df1
# 结合 df_中的路线页数 做个表的连接
df2=pd.pivot_table(df,values=['价格'],index={'出发地'},columns=['目的地'])
df2.head(10)
# 按照出发地和目的地 列举一下所有价格情况
df1=pd.pivot_table(df[df['出发地']=='杭州'],values=['价格'],index=['出发地','目的地'],columns=['去程方式'])
df1
# 按照出发地(杭州) 目的地,以及去程方式, 组合查询一下 所有的价格
#总的来说有点让我失望, 原本以为这里能分析出一些有趣的东西的
下午更新 另一部分
================================================================================
下午的更新 -----------------------------
import pandas as pd
# 9.3缺失值,异常值,重复值处理
# 9.3.1 缺失值处理
df=pd.read_csv('E:/python/python_test/pandas/data/pandas_data/hz_weather.csv')
df1=pd.pivot_table(df,values=['最高气温'],index=['天气'],columns=['风向'] )
# 检测方法
df1.isnull()
# 删除行或者删除列
#df1.dropna(axis=0)
#df1.dropna(axis=1)
# 0表示 每一行里边只要有True 就删除到这一行
# 1则是按照列进行分析
# 用字符串代替
#df1.fillna('missing')
# 前值代替
#df1.fillna(method='pad') # 只有从一行顺延,不能从上一列借用
# 后值代替
#df1.fillna(method='bfill',limit=1)
# 替代智能进行一次,因此 处理后第三行的数据还有个NaN, 同样最后一行就没有办法
# 这里我在想,有没有混合机制 ??
# 平均值代替
#df1.fillna(df1.mean())
# 默认是按照 每一列其他有效值的平均来算的 ,同样axis 参数无效
# 9.3.2 检测和过滤异常值
# 基于统计和数据分布
%matplotlib inline
import matplotlib as mpl
import matplotlib.pyplot as plt
df=pd.read_csv('E:/python/python_test/pandas/data/pandas_data/hz_weather.csv')
fig,ax=plt.subplots(1,1,figsize=[8,5])
ax.hist(df['最低气温'],bins=20)
d=df['最低气温']
zscore=(d-d.mean())/d.std()
df['isOutlier']= zscore.abs()>3
df['isOutlier'].value_counts()
# 这里不知道为什么 在cmd窗口中没有正常执行
# 平均值为miu, 方差是 delta^2, 按照约定,如果数值和平均值之间的差 超出 3#delta,它将是超出正太分布 99.9%范围,那么这千分之1的数值
#将会被认为是异常值
# 但是我有个小问题,就是 null 在数值中会被认为是多大呢 ?暂时和这个问题无关,
# 详细的就看图吧

# 箱式图分析
%matplotlib inline
import matplotlib as mpl
import matplotlib.pyplot as plt
df=pd.read_csv('E:/python/python_test/pandas/data/pandas_data/sale_data.csv')
fig,ax=plt.subplots(1,1,figsize=[8,5])
df_=df[df['位置']=='上海']
df_.boxplot(column="成交量",ax=ax)
d=df_['成交量']
print(d.describe())
df_['isOutlier']= d>d.quantile(0.75)
df_[df_['isOutlier']==True]
# 箱体图 就是通过 75% 分位来描述数据分布, 看图 箱体上下边界之外的数据,就作为异常值过滤掉了
# 原来的数据文件有点问题,我临时吧条件改成了 位置==上海

# 9.3缺失值,异常值,重复值处理
# 9.3.1 缺失值处理
df=pd.read_csv('E:/python/python_test/pandas/data/pandas_data/hz_weather.csv')
df1=pd.pivot_table(df,values=['最高气温'],index=['天气'],columns=['风向'] )
df.head()
# ---9.3.2 检测和过滤异常值
df.duplicated()
df.duplicated('最高气温').value_counts()
df.drop_duplicates('最高气温')
df.describe()
# 数据 基础操作
# 9.3.4 天气数据分析和处理 案例
#就是 检查重复值,以及 正太分布图和 箱体图的展示,有时间再好好练习一下
=========================================================================================
---稍后 回来 更新 时序和正则等用法
# 9.5 数据类型转换
import pandas as pd
df_pop=pd.read_csv('E:/python/python_test/pandas/data/pandas_data/european_cities.csv')
df_pop.head()
type(df_pop.Population[0])
# str ,要转成 int类型
df_pop['NumericPopulation']= df_pop.Population.apply(lambda x:int(x.replace(',','')))
df_pop.head()
# lambda 大概知道的,但是apply 不是 必须针对df的某一列呢 ??
df_pop['State'].values[:3]
df_pop['State']=df_pop['State'].apply(lambda x:x.strip())
df_pop.head()
# 这个是去除空格
df1=df_pop
df1.dtypes
df1.info()
df1.describe()
# 还有stack 和unstack
import pandas as pd
# 9.6 正则表达式
# 9.6.1 元字符和限定字符
#表格不写了
# 9.6.2 提取网页文本信息
import pandas as pd
df=pd.read_csv('E:/python/python_test/pandas/data/pandas_data/getlinks.csv')
df
df.link.str.extract('(\d+)')
# 超过不止一位的数字
# 这里 link.str.extact是针对 pd的方法,用户提取某类字符
df.link.str.extract('(.*)/(\d+)')
#
#df.link.str.extract('(?P<URL>.*)(?P<ID>\d+)')
# ?P<URL> 列名 ,指定列之后的 字符匹配。另一个是数字匹配
# 恕我直言, python的RE 我之前也是用过的, 不过和 shell的正则用起来 区别还是比较大的 ,好比德语和英语的区别这种
======================================================================
总结一下
1, df基本和sql 可以完美对接,数据的增删改, 表的连接,还有concat, 以及 对空值,异常值得鉴定和处理 , 至少支撑正则, sql 的正则好像是不支持的
2,忽然想到一个新的问题, 既然空值 和异常值可以快速获取,那么 从数据的角度来说, 做数据检查,应该还是可以的
对于异常值,我觉得 需要补充一部分 人为指定规则,来判定异常值得功能
3, df 任意列 含有 某某字符, 除了正则之外还有其他的方式么 ?
4,csv 和其他方式的转化, 也就是和mysqldb 之间的转化 ,还需要一些其他工具的
需要加强的地方
1,正太分布 和箱式图的使用
2,plt 绘图
3,正则使用
4,函数细节问题,
现在是 17:47

浙公网安备 33010602011771号