前言
用户量数据分析有几个关键步骤
1.获取用户行为数据(一般就是埋点数据)
2.对所有获取到的数据进行第一遍数据筛选
3.筛查后的数据进行基础的数据整理(主要就是数据的分组聚合等操作)
4.整理完成的数据转换成需要输出的数据格式(输出到文件,数据库等)
第一步
获取用户行为数据
一般用户的行为数据在数据库,比较多的由mysql,mongo,es等
本次就以es为例:
1.初始化es对象
Python学习交流Q群:906715085###
from elasticsearch import Elasticsearch
# 初始化es
es = Elasticsearch(
['10.10.3.13:19200', '10.10.3.15:19200', '10.10.3.41:19200'], # 连接集群,以列表的形式存放各节点的IP地址
sniff_on_start=True, # 连接前测试
sniff_on_connection_fail=True, # 节点无响应时刷新节点
sniff_timeout=60 # 设置超时时间
# 除开链接指定的IP地址外,其他的都可以不设置,使用默认值
)
2.获取es数据:这里写的比较简单,条件只有请求的时间范围,调用es的search方法查询,参数为index:索引名,doc_type:类型名,body:查询语句,这里完全就是dll语句,相比于java来说简单了很多
def get_es_data(startTime, endTime):
query = {
"query": {
"range": {
"requestTime": {
"gte": startTime,
"lte": endTime
}
}
},
"size": 50000
}
all_search = es.search(index="bury_point_log", doc_type="main", body=query) res = all_search['hits']['hits'] return res
在对这个语句的查询过程中,有一个弊端,数据量过大的时候,size也必须设置的很大,导致查询效率特别低,另外一种方式就是使用聚合语句,把本来要在panda中要做的事情,先在es中做掉一部分
这个查询效率就特别快
def get_es_data_agg():
query = {
"query": {
"range": {
"requestTime": {
"gte": "2022-05-01 00:00:00",
"lte": "2022-05-31 23:59:59"
}
}
},
"aggs": {
"appName": {
"terms": {
"field": "appName",
"size": 10 }, "aggs": {
"user": {
"terms": {
"field": "userId",
"size": 100000
} }
}
}
}
}
all_search = es.search(index="bury_point_log", doc_type="main", body=query)
第二步
对数据进行筛选,把获取到的数据转成成DataFrame,利于后续进行分组聚合
Python学习交流Q群:906715085###
def show_pd_message(items):
res = []
for item in items:
content = item['_source']
appTypeName = ''
if content.get('appName') == '1':
appTypeName = '家长端'
elif content.get('appName') == '2':
appTypeName = '教师端'
elif content.get('appName') == '3':
appTypeName = '后台'
content_filter = {
'appName': appTypeName, 'clientIp': content['clientIp'], 'module': content['requestRemark'],
'requestTime': content['requestTime'], 'userId': content['userId']}
res.append(content_filter)
indexs = [(i + 1) for i in range(len(res))]
columns = ['appName', 'clientIp', 'module', 'requestTime', 'userId']
pd_res = pd.DataFrame(res, columns=columns, index=indexs)
return pd_res
这里就是把需要的字段筛选出来,配合上colums和index,转换成panda对象。
第三步
数据整理
以对每个客户端用户数量进行统计为例,先对各客户端以及用户Id进行分组聚合,出来的对象再转换成需要的字典或者列表数据
def get_user_num(pd_res):
# 各端使用人数
# print(''' #
------------------各客户端数据使用情况(人次)--------------------- # ''')
result1 = pd_res.groupby(['appName', 'userId'], as_index=False).agg({
'module': 'size'})
res = result1.to_dict('records')
# print(result1)
res1 = {
}
for item in res:
if item['appName'] in res1.keys():
if item['userId'] != 'null':
origin_value = list(res1[item['appName']])
origin_value.append({
item['userId']: item['module']})
res1.update({
item['appName']: origin_value})
else:
res1.update({
item['appName']: [{
item['userId']: item['module']}]})
# print(res1)
return res1
第四步
数据输出
一般数据出来后,就会输出到数据库或者文件中,这里简单点就直接控制台打印出来
def user_num_data_anylsis(user_all_res):
family_user = ''
teacher_user = ''
for item in user_all_res:
if '家长端' in item.keys():
family_user_list = list(item['家长端'])
family_user = family_user + str(len(family_user_list)) + ','
else:
family_user = family_user + '0,'
if '教师端' in item.keys():
teacher_user_list = list(item['教师端'])
teacher_user = teacher_user + str(len(teacher_user_list)) + ','
else:
teacher_user = teacher_user + '0,'
print(last_month_next_start.split('-')[1] + "月:\n家长端人数" + family_user.split(',')[0] + "次\n教师端人数" +
teacher_user.split(',')[0] + "人")
print(last_month_start.split('-')[1] + "月:\n家长端人数" + family_user.split(',')[1] + "次\n教师端人数" +
teacher_user.split(',')[1] + "人")
# 环比
huanbi = ((int)(family_user.split(',')[1]) - (int)(family_user.split(',')[0])) / (int)(
family_user.split(',')[0]) * 100
print('家长端人数:' + last_month_start.split('-')[1] + '月环比' + str(round(huanbi, 2)) + '%')
huanbi1 = ((int)(teacher_user.split(',')[1]) - (int)(teacher_user.split(',')[0])) / (int)(
teacher_user.split(',')[0]) * 100
print('教师端人数:' + last_month_start.split('-')[1] + '月环比' + str(round(huanbi1, 2)) + '%')
最后的结果:
这一章的知识到这里就结束了,整体来说还是非常简单的,闲的无聊的时候拿来练手真的很nice,喜欢的小伙伴记得点赞收藏。