数据分析常用工具总结

numpy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1. 优点:向量化数据操作比for循环,速度大大加强,numpy array比list好的地方在于切片
2. array属性
np.random.random((2,2)) # 0-1随机数
np.random.randint(1,10,(3,3)) # 随机整数
array.shape, array.dtype # numpy两个属性
array.astype(np.float64) # 类型转换
3. array切片操作
a[0,1] # 第一个维度为0,第二个维度1,第三个维度全选,类似于a[0,1,:]
a[a>2] # boolean indexing, 利用broadcasting进行判断, 之后可以作为index进行数据的提取
a[a>2]=0 # 也可以对满足条件的元素进行赋值
4. array数学运算
broadcasting, 对不匹配的数据在高维上进行扩展,在取最小公倍数
np.sum(array) # 统计运算
np.dot # 矩阵乘法,点乘
np.multiply # 逐个元素乘法,对应相乘

#pandas

1
2
3
基于Numpy构建,利用它的高级数据结构和操作工具,可使数据分析工作变得更加便捷高效。
import numpy as np
import pandas as pd

基本数据结构

Series

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1. 基本概念
pd.__version__ # 查看版本
pd.Series # 可以使用不同类型,和list区别在于有index, 可以指定index

2. Series构建
pd.Series([1,2,3], index=['a', 'b', 'c'])
pd.Series({...}, name="xxx") # 通过对dictionary进行构建pandas, 给Series赋予名字

3. 切片
aseries[[1,4,3]]; aseries[1:]; aseries[:-1] # 数字下标切片,即使index不是数字也ok

4. 运算规则
series的相加是根据index对应相加的

5. 取值
数学运算也是broadcasting方式
'xxx' in aseries # 判断xxx是否在aseries的index中
aseries.get('xxx', 0) # 类似于字典
aseries[aseries<20] # boolean index也可以
aseries.median() # 除去缺失值之后进行统计运算
aseries['xxx'] = 1000 # 对aseries['xxx']重新赋值
np.square(aseries) # 对每个运算进行计算平方

DataFrame

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
1. 基本概念
一组Series集合在一起

2. DataFrame的构建
- pd.DataFrame({'a':[1,2,3], 'b':[1,4,3]}, columns = ['b', 'a'], index = ['one', 'two', 'three']) # 构建DF, 指定列名以及index名
- pd.DataFrame([{'a':100,'b':200}, {'a':200, 'b':300}], index=['one', 'two']) # 按照一行一行构建DF
- pd.DataFrame({'a':seriesa, 'b':seriesb} # 记住按照index对齐, 缺失值直接Nan填充

3. 元素的提取以及增加及逻辑操作及转置
- aDF['xxx']/aDF.xxx # 取出来的是一个Series
- aDF[['xxx']] # 取出来的是一个DF
- aDF.loc(['a','b'],['c','d']) # 取对应的数据
- aDF.loc[:, 'newcol'] = 2000 # 如果没有newcol那么就新加一列
- aDF.loc[(aDF['a']>10) & (aDF['b']<100), :] # 也可以给条件进行筛选,& | ~进行逻辑运算
- aDF.T # 进行转置
4. 数据读入以及基本信息以及删除
- pd.read_csv(path, sep='\t', index_col=''/int, usecols=[...], header=0, parse_dates=[0]/['Date']) # 读文件,第一列作为日期型,日期型处理参照: http://hshsh.me/post/2016-04-12-python-pandas-notes-01/
- aDF.to_csv('xxx.csv', sep='\t', index=True, header=True) # 写文件
- aDF.describe(include=[np.float64...]) / aDF.info() # 对数据进行统计,查看缺失值
- aDF.shape
- aDF.isnull() # 判断是是否为空
- aDF[aDF['xxx'].isnull(), :] = 10 # 对空值赋值
- aDF.notnull() # 查看是否有值
- aDF.drop(['one', 'two'], axis=0) # 对index为one和two的两行进行删除, axis=1删除列

5. 数据分组聚合
- aDF.groupby('name', sort=False).sum() # 对DF进行聚合操作,同时对相应聚合的列进行排序,然后计算其他值的和
- groupbyname=aDF.groupby('name'); groupbyname.groups; len(groupbyname) # 得到对应的各个组别包含的index, 并且可以获取对应的group长度
- aDF.groupby('name').agg([np.sum, np.mean, np.std]) # 对不同类别的数据进行各类运算, 每个name对应三列分别是分组之后np.sum, np.mean, np.std计算
- aDF.groupby('name').agg(['sum', 'median', 'mean']) # 和上面的作用相同
- aDF.groupby('name').agg(['a':np.sum, 'b':median, 'c':np.mean]) # 对不同列进行不同操作
- aDF.groupby(['name', 'year']).sum()/mean()/median()/describe() # 多组分类
- aDF.groupby(['name', 'year']).size() # 多组分类, 每一组有多少个记录
- 提取group类别名称以及类别对应的数据行
for name,group in groupbyname:
print(name) # 类别名称
print(group) # 名称对应的数据行
groupbyname.get_group('jason') # 可以得到对应组别的数据行,DF格式
6. transform/apply/filter 数据变换
transfrom可以对分组进行变换, apply对整个DF进行分类,filter对分组进行判断
- aDF['Date'].dt.dayofweek # 可以得到对应的日期中的第几天
- aDF.groupby(aDF.index.year).mean() # 可以对相应的日期型的年进行分组聚合
- aDF.groupby(aDF.index.year).transform(lambda x: (x-x.mean())/x.std()) # 对每一年的数据求均值以及标准差,并对每个数据进行操作,之所以没以每年为单位进行展示主要是跟function有关,因为之前的是mean之类的
- aDF.groupby(aDF.index.year).apply(lambda x: (x-x.mean())/x.std()) # 可以起到相同的效果
- aDF.loc[:,'new'] = aDF['xxx'].apply(afunc) # 可以对xxx这一列进行操作按照afunc进行操作,然后创建新的列
- aSer = pd.Series([1,1,2,2,2,3,3,4,5,5]); sSer.groupby(sSer).filter(lambda x:x.sum()>4) # 对ser进行过滤,留下那些和大于4的类别

7. 表格的拼接与合并(concat/append/merge/join)
- df1.append(df2, sort=False, ignore_index=True) # 追加在行上,同时忽略原先df1和df2的index,合并为新的index
- df1.append([df2, df3]) # 也可以追加两个DF, 参考: https://zhuanlan.zhihu.com/p/38184619
- pd.concat([df1.set_index('a'), df2.set_index('a')], sort=False, axis=1, join='inner') # 和上述利用merge在a字段上进行内连接的效果类似,因为concat是基于index进行连接的,merge可以不基于index,指定字段
- pd.concat([df1, df2, df3], keys=['a', 'b', 'c'], axis=0, join='outer', sort=False) #列对齐的方式对行进行拼接,缺少值则补充为None,可以对拼接的每个df进行key的命名,axis=1的时候行对齐列拼接; join指定连接方式,outer表示外连接,inner表示内连接,sort是否对合并的数据进行排序
- merge # 基于某个字段进行连接,之前的append和concat都是在行上或者列上进行连接的,merge类似于SQL里面的连接,可以指定某个字段或某几个字段,体现在on上,on接list就是多个字段为key
- pd.merge(df1, df4, on='city', how='outer'/'inner'/'left'/'right') # 基于两个表中的city字段进行表格的连接,把其他的列进行combine到一起,不指定on的话就会找字段相同的那个进行拼接,注意concat是基于index进行拼接的
- pd.merge(df1, df2, how='inner', left_index=True, right_on='id') # 对数据进行merge,左表以index作为连接关键字,右表用id作为关键字
8. 链家Case study流程
- pd.to_datetime() # 日期类型转换
- df.drop(droplist, inplace=True, axis=1) # 删除一些列
- aDF.describe(include='all') # 字符串变量也会同时统计
- aDF.sort_values(by = 'xxx').tail() # 找出更新最晚的20套,但是有可能同一天超过20套
- 如果对数据进行处理发现转换未果可能是因为数据有缺失,做异常处理,缺失值作为Nan
- aDF.nsmallest(columns='age', n=20) # 取出年龄最小的20个数据
- groupby().agg() 之后一般会使用reset_index() 对数据进行归置然后再进行操作,ascending=False
- adf.value_counts(normalize=True) # 默认是按照value进行排序的
- aDF.apply(lambda x: 'xxx' in x) # 筛选出xxx在某列的值中与否,返回Ture, False,正则表达式的字符串匹配
- 可以定义正则表达式对文本信息进行提取
def get_info(s, pattern, n):
result = re.search(pattern, s)
if result:
return result.group(n)
else:
return ''
- .astype(int) # 转换pd类型
- help(pd.Series.value_counts) # 打印帮助文档

python绘图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
1. pandas 绘图
- pd.date_range('2018/12/28', periods=10) # 产生日期格式, 以2018/12/28为起始产生以天为单位的日期时间list
- pandas绘图需要把横坐标作为index,之后再画图
- 折线图绘制需要注意各列幅度,否则数值不明显
- df.plot.bar() # barplot, stacked=True, 堆叠
- df.plot.barh() # 绘制水平的barplot
- df.plot.hist(bins = 20) # 绘制直方图,单维度
- df.plot.box() # 对每列去看一些分布outlier
- df.plot.area # 堆叠区域图
- df.plot.scatter(x='a', y='b') # 散点图
- df.plot.pie(subplots=True) # 绘制带图例的饼图

2. matplotlib 绘图
- plt.rcParams['figure.figsize'] = (12,8) / plt.figure(figsize=(12,8)) # 设置画布大小
- ax = plt.plot(x,y,color='green', linewidth='-', marker='./*/x', label=r'$y=cos{x}$'/r'$y=sin{x}$'/r'$y=\sqrt{x}$') # 绘图
- ax.spines['right'].set_color('none') # 去掉右边的边框
- ax.xaxis.set_ticks_position('bottem') # ??????????????
- plt.xticks([2,4,6], [r'a',r'b',r'c']) # 设置坐标轴刻度
- ax.spines['bottem'].set_position('data', 0) # 设置坐标轴从0开始
- plt.xlim(1,3) # 设置坐标位置
- plt.title() # 标题
- plt.xlabel(r'xxx', fontsize=18, labelpad=12.5) # 绘制label, r值的是不转义的,$$值的是markdown格式
- plt.text(0.8, 0.9, r'$$', color='k', fontsize=15) # 进行注解
- plt.scatter([8], [8], 50, color='m') # 在某个位置,点有多大,颜色是什么
- plt.annotate(r'$xxx$', xy=(8,8), xytext=(8.2, 8.2), fontsize=16, color='m', arrowprops=dict(arrowstyle='->', connectionstyle='arc3, rad=0.1', color='m')) # 对某个点进行注解, 进行加箭头等等
- plt.grid(True) # 网格线
- plt.plot(x, y) # xy应为np array,如果是pandas那么可以通过values进行取值转换
3. matplotlib 绘图case
- 文件解压
x = zipfile.ZipFile(xxx, 'r') # 解压文件夹
x.extractall('xxxdir') # 解压到某个文件夹下
x.close() # 记得关闭
- matplotlib.rc('figure', figsize=(14,7)) # 设置一下图片尺寸
- matplotlib.rc('font', size=14) # 设置字体
- matplotlib.rc('axes.spines', top=False, right=False) # 设置边线
- matplotlib.rc('axes', grid=False) # 设置网格
- matplotlib.rc('axes', facecolor='white') # 设置颜色
- fig,ax含义
fig,ax = plt.subplots() # 创建绘图对象之后对ax进行操作,相当于先fig=plt.figure()再ax=fig.add_subplot(1,1,1)
https://blog.csdn.net/htuhxf/article/details/82986440
- ax.fill_between(x, low, upper, alpha=) # 对回归进行置信度绘制
- ax2 = ax1.twinx() # 共享同一个x轴
- ax2.spines['right'].set_visible(True) # 对右侧坐标轴进行设置,得到相应的图
- 图的使用
关联分析:散点图,曲线图,置信区间曲线图,双坐标曲线图
分布分析:堆叠直方图, 密度图
组间分析:柱状图(带errorbar),boxplot,这个需要多看看,

4. seaborn 绘图
- 引入seaborn的同时也要引入matplotlib因为,是底层
- 颜色设置
sns.set(color_codes=True) # 一些集成的颜色
https://seaborn.pydata.org/tutorial/color_palettes.html
- sns.displot(x, kde=True, bins=20, rug=True, fit=stats.gamma) # histgram加密度线,样本分布情况, 拟合某些分布fit
- sns.kdeplot # 类似于上面的,kde是每个样本用正态分布画,如果样本多,高度就高,之后再做归一化
- sns.jointplot(x,y,data) # 绘制带有histgram以及散点图的图,两个变量
- sns.pairplot(df) # 直接绘制各个列之间的散点图以及对应的histgram,多个变量
- scatter plot的密度版
with sns.axes_style('ticks'):
sns.jointplot(x,y,data, kind='hex'/'kde',color='m') #相当于对点很多的时候,六角箱图就能体现出点的多少,kde是等高线,密度联合分布
- 多图绘制1
g = sns.PairGrik(df) # 各个列混合,产出n*n个格子
g.map_diag(sns.kdeplot) # 对角线绘制
g.map_offdiag(sns.kdeplot, cmap='Blues_d', n_levels=20) # 绘制对角线是kde密度图其他为等高线的图
- 多图绘制2
g = FaceGrid(row=[..],aspect=1.5, data=)
g.map(sns.boxplot, x, y, hue, hue_order=[], ...)
- 多图绘制3
g = sns.PairGrid(data, x_vars=[], y_vars=[], aspect=0.5, size=3.5)
g.map(sns.violinplot, palette='bright') # x_vars数量*y_vars数量个子图,然后每个子图都绘制violinplot
- 关联分析 sns.lmplot
· sns.lmplot(x, y, data) # 散点图+线性回归,95%置信区间,适用于连续值
· sns.lmplot(x, y, data, x_jitter=0.08) # 左右抖动, 点如果离得近,会把点左右抖动开,适用于离散值
· sns.lmplot(x, y, data, x_estimator=np.mean, ci=95, scatter_kws={'s':80}, order=2, robust=True) # 对于离散值还可以这样操作,先求均值和95置信区间,之后再进行拟合, scatter_kws对点进行操作,order是说对数据点进行二次方的分布,而不是线性分布,robust打开的作用是踢除异常点,然后再进行绘制图
· sns.lmplot(x, y, data, x_estimator=np.mean, ci=95, scatter_kws={'s':80}, order=1, robust=True, logistic=True) # 相当于是说对二值化的数据进行logistic回归拟合,sigmoid拟合
· sns.lmplot(x, y, data, hue, col, row, col_wrap, aspect=0.5) # 散点图.线性回归,95%置信区间,适用于连续值,hue进行分组类似于pandas里面的groupby, hue变量一定是个离散变量, col也可以加一个变量,可以把图分成多列,row可以多行,如果row,col以及hue都指定,那么相当于在pandas里面groupby三个内容,col_wrap用于之指定每个col中的绘图数量
- sns.residplot() # 残差图
- sns.barplot(x,y,hue,ci=None) # 是否打开置信区间
- sns.stripplot(x, y, data, jitter =True) # 基于x为离散数据的,类似于散点图的boxplot
- sns.swarmplot(x, y, data) # 蜂群图,类似于小提琴图的点版
- sns.boxplot()
- sns.violinplot(bw) # 属于kde以及boxplot的组合,既看了单变量分布,也看了各变量之间的差异
- sns.violinplot(split=True, hue, inner='stick') # split将hue为两个类型的进行拼接绘制小提琴图,stick,每个样本绘制竖线
- sns.countplot(x, data) # 绘制离散变量数量分布,类似于value_counts(),类似于barplot但是使用的统计量是数量
- sns.pointplot(x, y, hue) # 查看离散变量x以及hue在离散变量y上的差别,使用均值,画点
- sns.factorplot(x, y, hue, col, data, kind='swarm') # 是一种泛化的绘图函数
- a.savefig('xx') # 进行图片存储 plt函数
文章目录
  1. 1. numpy
    1. 1.1. 基本数据结构
      1. 1.1.1. Series
      2. 1.1.2. DataFrame
  2. 2. python绘图
|