《利用python进行数据分析》学习笔记(三)
来源:互联网 发布:电影级别剪辑软件 编辑:程序博客网 时间:2024/04/29 07:05
处理US Baby Names 1880-2010 data set
导入表格数据
import pandas as pdyears = range(1880, 2011)pieces = []columns = ['name', 'sex', 'births']for year in years: path = 'ch02/names/yob%d.txt' % year frame = pd.read_csv(path, names=columns) # 添加year列 frame['year'] = year pieces.append(frame)# 把所有数据拼接到一个dataframe里names = pd.concat(pieces, ignore_index=True)
read_csv本身读进来是一个dataframe,但是因为我们要利用for循环读取多个并将它们依次append于一个list中,所以最后需要利用pd.concat()将list中的所有dataframe合并为一个。 ignore_index=True是为了重置index。
- names数据
数据聚合与重建
# 在year和sex上对names进行聚合total_births = names.pivot_table('births', index='year', columns='sex',aggfunc=sum)# 按性别和年度统计的总出生数total_births.plot(title='Total births by sex and year')# 插入prop列,用来存放指定名字的婴儿数相对于总出生数的比例def add_prop(group): # 整数除法会向下取整 births = group.births.astype(float) group['prop'] = births / births.sum() return groupnames = names.groupby(['year', 'sex']).apply(add_prop)# 检验所有分组的prop总和是否足够近似于1np.allclose(names.groupby(['year', 'sex']).prop.sum(), 1)# 取出每对sex/year组合的前1000个名字def get_top1000(group): return group.sort_index(by='births', ascending=False)[:1000]grouped = names.groupby(['year', 'sex'])top1000 = grouped.apply(get_top1000)
total_births画图(按性别和年度统计的总出生数)
names
- pandas.DataFrame.groupby
具体参数不在这里赘述,请参考下面文档,这里讲讲自己的试验与理解。
http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.groupby.html
groupby从字面上很好理解,就是我们根据一些columns,来对数据进行group聚合,问题是groupby后的数据到底是什么样的,无法正确理解数据形式就很难进行后面的处理,于是做了试验:
# 因为groupby对象是无法直接输出的,除非使用了sum,mean,size等函数才行,# 所以我们利用for和append把它的内在结构拉出来看看结果如何yy = names.groupby(['year','sex'])xx = []for y in yy: xx.append(y)xx
下面是xx的输出结果,只提取一部分
[((1880, 'F'), name sex births year prop 0 Mary F 7065 1880 0.077643 1 Anna F 2604 1880 0.028618 2 Emma F 2003 1880 0.022013 3 Elizabeth F 1939 1880 0.021309 4 Minnie F 1746 1880 0.019188 ... ... ... ... ... ... 940 Vertie F 5 1880 0.000055 941 Wilma F 5 1880 0.000055 [942 rows x 5 columns]), ((1880, 'M'), name sex births year prop 942 John M 9655 1880 0.087381 943 William M 9533 1880 0.086277
那么现在就很明了了,个人理解,groupby对象是一个具有multi-index的dataframe,它是由多个dataframe组合而成,而且每个dataframe具有自己的index,比如这里的话就是[‘year’,’sex’]((1880,’F’)对应的是一个dataframe,(1880,’M’)又对应一个dataframe)。所以当它们应用sum,mean,size之后,就相当于把一个dataframe压缩成了一行,这样拼起来又是一个一般的二维dataframe就可以输出了。
pandas.DataFrame.apply
接下来介绍apply,同样具体参数不在这里赘述了,请参考下面文档,在这里主要讲讲自己的理解。
http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.apply.html
首先提一下关于apply和map的区别,都是映射函数,apply是应用于dataframe的,而map是应用于series的。官方文档中,对apply的描述是将函数应用到dataframe的输入轴向上,对于一般的dataframe(也就是单一index),那么axis=0,就可以理解为是将每个column提出来输入到函数中(也就是一个个Series)。而代码中是将groupby后的对象输入到函数中,上面讲了groupby对象是具有multi-index的,那么这次应用到输入轴向的话,就不再是应用于每个column,而是应用于每个小的dataframe,这样的话,函数add_prop就好理解了。numpy.allclose
https://docs.scipy.org/doc/numpy/reference/generated/numpy.allclose.html
分析命名趋势
# 将前1000个名字分为男女两个部分boys = top1000[top1000.sex == 'M']girls = top1000[top1000.sex == 'F']# 按year和name统计的总出生数透视表total_births = top1000.pivot_table('births', index='year', columns='name', aggfunc=sum)# 对这4个名字按年份绘图subset = total_births[['John', 'Harry', 'Mary', 'Marilyn']]subset.plot(subplots=True, figsize=(12, 10), grid=False, title="Number of births per year")### 评估命名多样性的增长## 方法一# 计算最流行的1000个名字所占的比例,再按year和sex进行聚合并绘图table = top1000.pivot_table('prop', index='year', columns='sex', aggfunc=sum)table.plot(title='Sum of table1000.prop by year and sex', yticks=np.linspace(0, 1.2, 13), xticks=range(1880, 2020, 10))## 方法二# 统计占总出生人数钱50%的不同名字的数量def get_quantile_count(group, q=0.5): group = group.sort_index(by='prop', ascending=False) return group.prop.cumsum().values.searchsorted(q) + 1diversity = top1000.groupby(['year', 'sex']).apply(get_quantile_count)diversity = diversity.unstack('sex')# diversity画图diversity.plot(title="Number of popular names in top 50%")
total_births
subset画图(几个男孩和女孩名字随时间变化的使用数量)
table画图(分性别统计的前1000个名字在总出生人数中的比例)
diversity画图(前50%人数中,名字的个数)
numpy.searchsorted(a,v,side=’left’)
在一个sorted的数组a中,找到indices,使得对应的v插入到这些indices之前,a数组的顺序能够不变
https://docs.scipy.org/doc/numpy/reference/generated/numpy.searchsorted.html
最后一个字母的变革
# 从name column里面提取最后一个字母get_last_letter = lambda x: x[-1]last_letters = names.name.map(get_last_letter)last_letters.name = 'last_letter'# 按照年龄,字母和性别进行聚合形成透视表table = names.pivot_table('births', index=last_letters, columns=['sex', 'year'], aggfunc=sum)# 选出具有一定代表性的年份数据subtable = table.reindex(columns=[1910, 1960, 2010],level='year')subtable.sum()# 求出末位字母所占比例letter_prop = subtable / subtable.sum().astype(float)# 生成各年度男孩女孩各个末字母的比例的条形图fig, axes = plt.subplots(2, 1, figsize=(10, 8))letter_prop['M'].plot(kind='bar', rot=0, ax=axes[0], title='Male')letter_prop['F'].plot(kind='bar', rot=0, ax=axes[1], title='Female', legend=False)# 各年出生的男孩中名字以d/n/y结尾的人数的比例letter_prop = table / table.sum().astype(float)dny_ts = letter_prop.ix[['d', 'n', 'y'], 'M'].Tdny_ts.plot()
letter_prop[‘M’]和letter_prop[‘F’]画图(男孩女孩中各个末字母的比例)
dny_ts画图(各年出生的男孩中名字以d/n/y结尾的人数比例)
变成女孩名字的男孩名字(以及相反情况)
# 名字去重all_names = top1000.name.unique()# 对all_names的所有元素进行判定,以'lesl'开头的名字将会标为True,其余的为False,也就是说mask是一个布尔量的数组mask = np.array(['lesl' in x.lower() for x in all_names])# 再利用布尔索引取出开头为'lesl'的名字lesley_like = all_names[mask]# 过滤掉其他名字filtered = top1000[top1000.name.isin(lesley_like)]filtered.groupby('name').births.sum()# 按性别和年度进行聚合,并按年度进行规范化处理,算出比例table = filtered.pivot_table('births', index='year', columns='sex', aggfunc='sum')table = table.div(table.sum(1), axis=0)# 绘制一张分性别的年度曲线图table.plot(style={'M': 'k-', 'F': 'k--'})
table画图(各年度使用”Lesley型”名字的男女比例)
pandas.DataFrame.div
http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.div.html
- 《利用python进行数据分析》学习笔记(三)
- 利用Python进行数据分析 学习笔记
- 利用Python进行数据分析(三)
- 《利用python进行数据分析》学习笔记(一)
- 利用python进行数据分析(学习笔记)
- 《利用python进行数据分析》学习笔记(一)
- 《利用python进行数据分析》学习笔记(二)
- 《利用python进行数据分析》学习笔记(四)
- 《利用python进行数据分析》学习笔记(六)
- 利用python进行数据分析学习笔记—python基础知识
- 《利用Python进行数据分析》第二章-学习笔记
- 《利用Python进行数据分析》学习笔记ch02-1(1)
- 《利用Python进行数据分析》学习笔记ch02-2(2)
- 《利用Python进行数据分析》学习笔记ch02-3(3)
- 《利用Python进行数据分析》学习笔记ch03(4)
- 《利用Python进行数据分析》学习笔记ch04(5)
- 《利用Python进行数据分析》学习笔记ch05(6)
- 《利用Python进行数据分析》学习笔记ch06(7)
- 积分电路原理之新解——放大器与电容的变身
- 暗云Ⅲ: 迄今为止最复杂的木马之一
- 【视频开发】【CUDA开发】英伟达CUVID硬解,并通过FFmpeg读取文件
- 一首半咸不淡的诗
- keras 自定义 loss损失函数, sample在loss上的加权 和 metric
- 《利用python进行数据分析》学习笔记(三)
- java IE11浏览器文件下载的文件名乱码
- 2017-06-15 HIVE2
- MYSQL 总结(四)
- Git分支管理规范和解析
- 自行实现 Onvif 对接开发模式
- 同源策略和Jsonp跨域请求解析
- 医学图像分割--Stacked fully convolutional networks with multi-channel learning
- 基于 MongoDB 及 Spring Boot 的文件服务器的实现