[color=rgba(0, 0, 0, 0.75)]从题目来看,这节课应该是探究某一事物随着时间推移而发生的变化情况。所以核心内容应该是探究时间序列数据变化趋势。详细如下:
一、 取数据[color=rgba(0, 0, 0, 0.75)]数据来源:http://jmcauley.ucsd.edu/data/amazon/links.html

亚马逊电子商务网站,提供了一些数据资源,上图页面上的数据为1996年5月至2014年7月,20余年的商品评论。Ratings only 数据的表头为“user,item,rating,timestamp”
我们下载“Musical Instruments”中的评论文件。(这个数据下载非常慢,几乎需要一天的时间),可以使用老师已下载的文件:https://www.njcie.com/python/2时间分析/
【脚本】
rnames = ['uid', 'pid', 'rating', 'timestamp']ratings = pd.read_csv('D:\\ratings_Musical_Instruments.csv', header=None, names=rnames)2、处理时间戳
【脚本】
ratings['date'] = ratings['timestamp'].apply(datetime.fromtimestamp)ratings['year'] = ratings['date'].dt.yearratings['month'] = ratings['date'].dt.month
ratings= ratings['date'].to_period(freq='M')
print(ratings)
【结果】
date uid pid rating timestamp year month
2014-03 A1YS9MDZP93857 0006428320 3.0 1394496000 2014 3
2013-06 A3TS466QBAWB9D 0014072149 5.0 1370476800 2013 6
【说明】
- 时间戳是一个整数,是1970-01-01 00:00:00至统计时间的秒数。
- datetime.fromtimestamp()将时间戳数据转为datetime数据
- 注意datatime数据转换为时期数据时,需要指明索引列,同时需要将转换后的dataframe赋给一个DF变量。即:ratings= ratings[‘date’].to_period(freq=‘M’)
【脚本1】
pingFen = ratings['rating'].groupby('date').mean()plt.plot(pingFen)plt.show()
【脚本2】
pingFen = ratings['rating'].groupby('date').mean()plt.plot(pingFen.to_timestamp())
plt.show()
【结果】
脚本1报错,提示:TypeError: float() argument must be a string or a number, not ‘Period’,意思是在画图时,period类型错误,需要字符或数值型。
脚本2的结果为:
[color=rgba(0, 0, 0, 0.749019607843137)]
【说明】
1) 这里没有指明对哪个商品的评分,只是对“乐器类”产品的整体评分。
2) 可以看出,乐器类商品的评分在2004年以后趋于平稳,1998年至2004年,评分为下降趋势。
因为以上结果似乎忽略了一个因素,就是评分参与人的多少,极端情况下,参与人越少,评分越不稳定,代表性越差。我们看一下评分人数:
【脚本】
plt.plot(pingFenR.to_timestamp())
plt.show()
【结果】
[color=rgba(0, 0, 0, 0.749019607843137)]
【说明】
由图我们看出,2010年之前,参评的人数很少,2010年以后,参评人快速增加,所以分析1中,2010年以后的评分均值更稳定,也可以说这个阶段的数据更有意义。
那么怎样将三个维度的数据展现在同一张图中,包含时间、参评人数、评分均值?
带大小的散点图!
[color=rgba(0, 0, 0, 0.749019607843137)]【脚本】
plt.scatter(pingFen.index.to_timestamp(),pingFen['rating']['mean'], ingFen['rating']['count'])
plt.show()
[color=rgba(0, 0, 0, 0.75)]【结果】

【说明】
对比plt.scatter()和plt.plot()中,将时期索引转为时间戳时,是不是有所不同?
plt.plot()中为:pingFen.to_timestamp()
plt.scatter()中为:pingFen.index.to_timestamp()
而且plt.scatter()中只能用加index的引用,而plt.plot()中加index不加都可以
这是为什么呢?== 关于这一点我不太明白,有知道的人可以留言哦~ ==
有时我们显示出散点的大小区别不明显,我们就可以通过将点的大小的参数乘或除一个数值的方法来调整;
如:我上面形成的图中,有的点太大,调小的方法如下:
结果如下图:
[color=rgba(0, 0, 0, 0.749019607843137)]
将所有数据映射到0~1之间,方法(n-min)/(max-min)。
我试用了以下脚本,结果报错了
(pingFen['count']-pingFen['count'].min())/(pingFen['count'].max())
提示:KeyError: ‘count’
原因应该是,这个评分表(pingFen)中不存在一个字段叫‘count’,count只是算法。
解决方法如下:
pingFen['sl'] = (pingFen['cnt']-pingFen['cnt'].min())/(pingFen['cnt'].max())
这里我特别说一下agg()函数,理解该函数可真很费了我一翻工夫。
【关于pandas中的agg()的用法说明】
[color=rgba(0, 0, 0, 0.749019607843137)]
参数详细信息,可以参见https://www.jb51.net/article/127806.htm
我这里使用的脚本为:
[color=rgba(0, 0, 0, 0.75)]
pingFen = ratings.groupby('date').agg(cnt=('rating', 'count'), avg =('rating', 'mean'))
pingFen['sl'] = (pingFen['cnt']-pingFen['cnt'].min())/(pingFen['cnt'].max())
plt.scatter(pingFen.index.to_timestamp(), pingFen['avg'], s=pingFen['sl']*1500, c=pingFen['cnt']/pingFen['cnt'].mean(), alpha=0.3)
对scatter()的解读如下:
调整后效果如下图,这是我梦寐以求的靓图,虽然并不是最好的:
[color=rgba(0, 0, 0, 0.749019607843137)]
[color=rgba(0, 0, 0, 0.75)][LaTex]
[color=rgba(0, 0, 0, 0.75)]【说明】
图中x轴为时间
y轴为评分的平均分,从图中可以看出,2006年以后,评分的平均分集中在4.1分至4.5分之间
点的大写为参与评分的人数,从图中可以看出2012年以后参与评分的人数远大与2004年以前的评分人数,因此其分值更有价值
颜色表示的信息是可以配置的,因为本例中没有引入太多观察数据的维度,我这里仍使用评分人数来显示颜色,紫色表示人数少,黄色表示人数多,绿色居中。
[color=rgba(0, 0, 0, 0.75)]【完】
[color=rgba(0, 0, 0, 0.75)][/LaTex]


雷达卡




京公网安备 11010802022788号







