上集:临时处理小记:把Numpy的narray二进制文件转换成json文件
对网站日记分析其实比较常见,今天模拟演示一下一些应用场景,也顺便说说Pandas,图示部分也简单分析了下
一般数据都不可能直接拿来用的,或多或少都得清理一下,我这边就模拟一下清洗完的数据
%%time
import numpy as np
import pandas as pd
Wall time: 520 ms
%%time
# 生成一个2017年的所有时间点(分钟为单位)
datetime_index = pd.date_range("2017-01-01","2018-01-01",closed="left",freq="min")
Wall time: 4 ms
%%time
# 简单查看一下
datetime_index # 如果你不想取到2018.01.01 00:00:00就设置~闭区间closed="left"
Wall time: 0 ns
DatetimeIndex(['2017-01-01 00:00:00', '2017-01-01 00:01:00',
'2017-01-01 00:02:00', '2017-01-01 00:03:00',
'2017-01-01 00:04:00', '2017-01-01 00:05:00',
'2017-01-01 00:06:00', '2017-01-01 00:07:00',
'2017-01-01 00:08:00', '2017-01-01 00:09:00',
...
'2017-12-31 23:50:00', '2017-12-31 23:51:00',
'2017-12-31 23:52:00', '2017-12-31 23:53:00',
'2017-12-31 23:54:00', '2017-12-31 23:55:00',
'2017-12-31 23:56:00', '2017-12-31 23:57:00',
'2017-12-31 23:58:00', '2017-12-31 23:59:00'],
dtype='datetime64[ns]', length=525600, freq='T')
%%time
# 查看多少元素
datetime_index.size # 用len()也一样
Wall time: 0 ns
525600
%%time
# 创建一个DataFrame,以时间轴为index
log_df = pd.DataFrame(index=datetime_index)
Wall time: 999 µs
%%time
# 随机生成一波访问人数
log_df["访问人数"] = np.random.randint(10,50,size=datetime_index.size)
# 随机生成一波注册人数
log_df["注册人数"] = np.random.randint(3,size=datetime_index.size)
Wall time: 31.2 ms
# 查看前10条
log_df.head(10)
访问人数 | 注册人数 | |
---|---|---|
2017-01-01 00:00:00 | 42 | 0 |
2017-01-01 00:01:00 | 31 | 0 |
2017-01-01 00:02:00 | 17 | 1 |
2017-01-01 00:03:00 | 46 | 0 |
2017-01-01 00:04:00 | 41 | 1 |
2017-01-01 00:05:00 | 49 | 1 |
2017-01-01 00:06:00 | 44 | 2 |
2017-01-01 00:07:00 | 27 | 2 |
2017-01-01 00:08:00 | 30 | 0 |
2017-01-01 00:09:00 | 36 | 1 |
# 查看后10条
log_df.tail(10)
访问人数 | 注册人数 | |
---|---|---|
2017-12-31 23:50:00 | 38 | 0 |
2017-12-31 23:51:00 | 31 | 2 |
2017-12-31 23:52:00 | 45 | 2 |
2017-12-31 23:53:00 | 44 | 0 |
2017-12-31 23:54:00 | 32 | 2 |
2017-12-31 23:55:00 | 31 | 2 |
2017-12-31 23:56:00 | 45 | 2 |
2017-12-31 23:57:00 | 18 | 2 |
2017-12-31 23:58:00 | 12 | 2 |
2017-12-31 23:59:00 | 17 | 0 |
# 查看有多少数据
log_df.size
1051200
# 矩阵形状
log_df.shape # 525601行,2列
(525600, 2)
%%time
# 简明摘要
log_df.info()
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 525600 entries, 2017-01-01 00:00:00 to 2017-12-31 23:59:00
Freq: T
Data columns (total 2 columns):
访问人数 525600 non-null int32
注册人数 525600 non-null int32
dtypes: int32(2)
memory usage: 8.0 MB
Wall time: 12 ms
%%time
# 初略统计一下
log_df.describe()
Wall time: 62.5 ms
访问人数 | 注册人数 | |
---|---|---|
count | 525600.000000 | 525600.000000 |
mean | 29.498189 | 1.000936 |
std | 11.547677 | 0.815972 |
min | 10.000000 | 0.000000 |
25% | 19.000000 | 0.000000 |
50% | 29.000000 | 1.000000 |
75% | 40.000000 | 2.000000 |
max | 49.000000 | 2.000000 |
来个简单版,主要学会方法,数据用真实数据后显示会更人性化,比如可以看到哪几个月份增长比较快,那几个月比较慢
然后还可以运用于公司花钱弄推广,以前是听别的公司忽悠,可能找了很多僵尸用户,数据貌似上去了,但是你做个年度统计,看看真实活跃的用户就知道推广的成效究竟几何了
%%time
from matplotlib import pyplot as plt
Wall time: 179 ms
%%time
p_s = log_df["访问人数"].resample("D").sum() # 平均可以看mean()
r_s = log_df["注册人数"].resample("D").sum()
day_df = pd.DataFrame()
day_df["访问人数"] = p_s
day_df["注册人数"] = r_s
Wall time: 49 ms
day_df.head(10)
访问人数 | 注册人数 | |
---|---|---|
2017-01-01 | 42319 | 1400 |
2017-01-02 | 41820 | 1438 |
2017-01-03 | 42256 | 1431 |
2017-01-04 | 42097 | 1488 |
2017-01-05 | 42734 | 1498 |
2017-01-06 | 41733 | 1424 |
2017-01-07 | 43016 | 1503 |
2017-01-08 | 42480 | 1427 |
2017-01-09 | 42791 | 1428 |
2017-01-10 | 41838 | 1441 |
# 快速查看一下2017年1月份的统计
day_df["2017-01"]
访问人数 | 注册人数 | |
---|---|---|
2017-01-01 | 42319 | 1400 |
2017-01-02 | 41820 | 1438 |
2017-01-03 | 42256 | 1431 |
2017-01-04 | 42097 | 1488 |
2017-01-05 | 42734 | 1498 |
2017-01-06 | 41733 | 1424 |
2017-01-07 | 43016 | 1503 |
2017-01-08 | 42480 | 1427 |
2017-01-09 | 42791 | 1428 |
2017-01-10 | 41838 | 1441 |
2017-01-11 | 42256 | 1464 |
2017-01-12 | 42766 | 1464 |
2017-01-13 | 42688 | 1428 |
2017-01-14 | 42436 | 1418 |
2017-01-15 | 42639 | 1429 |
2017-01-16 | 43862 | 1476 |
2017-01-17 | 41876 | 1489 |
2017-01-18 | 42821 | 1437 |
2017-01-19 | 43000 | 1399 |
2017-01-20 | 43158 | 1454 |
2017-01-21 | 42722 | 1479 |
2017-01-22 | 41985 | 1444 |
2017-01-23 | 43127 | 1460 |
2017-01-24 | 42949 | 1382 |
2017-01-25 | 42044 | 1460 |
2017-01-26 | 42809 | 1475 |
2017-01-27 | 42387 | 1450 |
2017-01-28 | 42895 | 1486 |
2017-01-29 | 41565 | 1478 |
2017-01-30 | 42523 | 1433 |
2017-01-31 | 42027 | 1488 |
day_df["2017-01"].index
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
'2017-01-05', '2017-01-06', '2017-01-07', '2017-01-08',
'2017-01-09', '2017-01-10', '2017-01-11', '2017-01-12',
'2017-01-13', '2017-01-14', '2017-01-15', '2017-01-16',
'2017-01-17', '2017-01-18', '2017-01-19', '2017-01-20',
'2017-01-21', '2017-01-22', '2017-01-23', '2017-01-24',
'2017-01-25', '2017-01-26', '2017-01-27', '2017-01-28',
'2017-01-29', '2017-01-30', '2017-01-31'],
dtype='datetime64[ns]', freq='D')
# 比如绘制一份1月份的访问人数一览表
plt.plot(day_df["2017-01"].index,day_df["2017-01"]["访问人数"])
plt.show()
按照图看,15号这天用户数陡然增加,然后第二天用户骤降。
可以看看是不是被DDOS了,或者有没有用户恶意刷单 or 是不是爬虫,这时候可以采取对应的措施
# 比如绘制一份1月份的注册人数一览表
plt.plot(day_df["2017-01"].index,day_df["2017-01"]["注册人数"])
plt.show()
按照上图看,23号这天不正常,是否前端时间推广太疯狂用户反弹,或者说这天服务器出问题了
这边直接使用Pandas提供的简单绘图方法
%%time
# 统计一下以月为单位的人数信息
p_s = log_df["访问人数"].resample("M").sum()
r_s = log_df["注册人数"].resample("M").sum()
month_df = pd.DataFrame()
month_df["visitors"] = p_s
month_df["register"] = r_s
Wall time: 53 ms
month_df.tail(10)
visitors | register | |
---|---|---|
2017-03-31 | 1314899 | 44706 |
2017-04-30 | 1276451 | 43277 |
2017-05-31 | 1316778 | 44447 |
2017-06-30 | 1276800 | 42979 |
2017-07-31 | 1319003 | 44382 |
2017-08-31 | 1316498 | 44514 |
2017-09-30 | 1275093 | 43299 |
2017-10-31 | 1313942 | 44666 |
2017-11-30 | 1271139 | 43599 |
2017-12-31 | 1315168 | 44846 |
# 具体项你可以指定
plt.plot(month_df.index,month_df["visitors"])
plt.show() # 图中3月是低谷
%%time
# 默认是折线图
month_df.plot()
# 密度图
month_df.plot.density()
# 柱形图(叠图,可以计算百分比)
month_df.plot.bar(stacked=True)
# 水平柱形图
month_df.plot.barh() # stacked=True
# 显示一下
plt.show()
Wall time: 720 ms
%%time
# 季度统计
quarter_df = pd.DataFrame()
quarter_df["visitors"] = log_df["访问人数"].resample("Q").sum()
quarter_df["register"] = log_df["注册人数"].resample("Q").sum()
Wall time: 44 ms
# 饼状图
quarter_df.plot.pie(subplots=True,labels=["Spr","Sum","Aut","Win"])
plt.show()
从图片来看,基本均匀的