python计算json格式数据的pv和uv(也可用dataframe)
测试数据放在example1.log文件中,也可自己写几个测试数据,类似如下:
{“name”:“Betty”,“age”:15,“email”:“123@123.com”,“request”:"/report/detail",“remote_addr”:“63.23.126”}
{“name”:“Nora”,“age”:16,“email”:“124@124.com”,“request”:"/report/detail",“remote_addr”:“63.23.127”}
{“name”:“Alie”,“age”:17,“email”:“125@125.com”,“request”:"/report/news/detail",“remote_addr”:“63.23.127”}
{“name”:“Mary”,“age”:18,“email”:“126@126.com”,“request”:"/report/news/detail",“remote_addr”:“63.23.128”}
{“name”:“Alie”,“age”:17,“email”:“125@125.com”,“request”:"/report/detail",“remote_addr”:“63.23.127”}
python处理语句如下:
import json
import pandas as pd
f=open("example1.log",'r',encoding="utf-8") #读取文件
s=[]
for line in f:
line=line.replace("\\","\\\\") #处理下斜杠
s.append(json.loads(line)) #将每行的数据处理后放入列表中
df=pd.DataFrame(s)
df_copy=df.copy()
df #展示下数据
s
#可以看到s是个列表里面装的一个个字典格式的数据,这种类型的数据可以变成pandas的dataframe格式的数据
#df_copy_t1=df_copy.iloc[:,[0,4]]
#df_copy_t1
L=[]
U=[]
for i in s: #读取列表里的字典
for a,b in i.items(): #读取字典的key、value
if a=="request": #拿取所有被访问的网址存放在L列表中
L.append(b)
if a=="remote_addr": #拿取所有的用户ip存放在U列表中
U.append(b)
H=list(zip(L,U))
m=list(set(L))
#总体思路就是两个循环,一个循环读取已经去重过的request,在里面再来另一个循环读取每一个request和remote_addr,然后当读取的request和外面循环的request相等时就数值加1,这是pv的,如果是uv的话需要再判断一下这个地址是否已经被读取过了,只有是新的地址才会加1。将request和K值更新到新的字典中。
这里循环的次数就会是两个列表中元素数量相乘,一旦数据量较大时就会占用很多资源,导致跑起来很慢。循环的写法肯定有更简单的方法,但现在懒得想。。。。(因为发现dataframe会很简单快捷)
def pv(m,H):
dic={}
for i in m:
k=0
for j in H:
if j[0]==i:
k=k+1
dic.update({j[0]:k})
return dic
def uv(m,H):
dic={}
for i in m:
k=0
d=[]
for j in H:
if j[0]==i and j[1] not in d:
k=k+1
d.append(j[1])
dic.update({j[0]:k})
return dic
print(pv(m,H))
print(uv(m,H))
#如上写法跑大批量数据较慢,所以还有种dataframe的groupby计数可以很快速处理数据得到pv和uv,见如下
```python
#dataframe计算pv和uv
#计算pv
data_df1=df_copy.groupby(by="request")['remote_addr'].count().reset_index()
data_df1
#计算UV
data_df2=df_copy.groupby(by="request")['remote_addr'].nunique().reset_index()
data_df2