一、数据清洗

1.1 数据集合并

"""
1  同一文件夹下多个格式相同的数据集合并
path为文件夹所在位置,例如path = 'D:/3. shiyan/data' ,data = MergeData(path)

调用:
path = 'D:/3. shiyan/data' 
data = MergeData(path)
"""

def MergeData(path):
    import os
    import pandas as pd

#     path = 'D:/3. shiyan/data'   #设置csv所在文件夹
    path = path
    files = os.listdir(path)  #获取文件夹下所有文件名形成一个列表

    df1 = pd.read_csv(path + '/' + files[0],encoding='utf-8',error_bad_lines=False)#读取首个csv文件,保存到df1中

    for file in files[1:]:     
        df2 = pd.read_csv(path +'/' +  file,encoding='utf-8',error_bad_lines=False ) #打开csv文件,注意编码问题,保存到df2中
        df1 = pd.concat([df1,df2],axis=0,ignore_index=True)  #将df2数据与df1合并

    df1 = df1.drop_duplicates()   #去重
    df1 = df1.reset_index(drop=True) #重新生成index
    df1.to_csv(path + '/' + 'total.csv') #将结果保存为新的csv文件
    return df1

1.2 公司代码处理

"""
公司代码处理
需求数据需有公司代码列,例如data['companyCode'] = data['companyCode']
"""
def companyCodeDeal(df3):
    import numpy as np
    df3=df3.dropna(subset=['companyCode'])   # 去除companyCode列空值行
    df3['companyCode'] = df3['companyCode'].astype(np.int64) # 转换数据列类型,去掉末尾.0
    df3['companyCode']=df3['companyCode'].astype(str).str.zfill(6) # 补齐代码前面的0
    return df3

1.3 去除干扰项

def removeInterference(data1):
    data1 = data1[~data1['companyCode'].str.startswith('99')]
    data1 = data1[~data1['companyCode'].str.contains('600036')]
    data1 = data1[~data1['companyCode'].str.contains('589618')]
    data1 = data1[~data1['companyCode'].isin(['188027'])]
    data1 = data1[~data1['companyCode'].isin(['188026'])]
    data1 = data1[~data1['companyCode'].isin(['825000'])]
    data1 = data1[~data1['companyCode'].isin(['826000'])]
    return data1

1.4 时间戳处理,将UTF时间改为北京东八区时间

"""
时间戳处理,将UTC时间改为东八区时间
被处理数据需有@timestamp列
"""
def timestampDeal(df3):
    # 时间处理,将UTC时间改为东八区时间,并将date和time分隔
    import datetime
    import pandas as pd
    df3['date'] = pd.to_datetime(df3['@timestamp'])   # 将@timestamp数据转化为datetime64类型保存到date中
    df3['date'] = (df3['date'] + datetime.timedelta(hours=8))  # utc时间改为东八区时间+8h
    # 将时间和日期分隔
    df3['time']= df3['date']    # 复制date 列数据到 time 
    df3['date'] = df3.date.dt.date # 提取年月日
    df3['time'] = df3.time.dt.time  # 提取时间
    # 将time列排序到第二列位置
    df_time = df3.time
    df3 = df3.drop('time',axis = 1)
    df3.insert(1,'time',df_time)
    # 将date列数据排到第二列位置
    df_date = df3.date
    df3 = df3.drop('date',axis = 1)
    df3.insert(1,'date',df_date)

    df3.loc[:'time' ] = df3.loc[:'time'].astype('str')  # 将所有格式转化为object
    df3['time'] = df3['time'].str[0:8]  #截取用户行为时间区域,去掉末尾秒后面微秒区域
    return df3

二、日志分析(提取相关模块数据后可进行基础日志分析)

data = data.loc[data["recordModule"] == "相关模块"]

2.1 用户群体划分

"""
用户群体划分
"""
def listedCompanyExtract(df3):  # 上市公司
    import pandas as pd
    d1 = df3[df3.companyCode.str.startswith('00')]  # 中小板和深主板
    d2 = df3[df3.companyCode.str.startswith('30')]  # 创业板
    d3 = df3[df3.companyCode.str.startswith('43')]  # 新三板
    d4 = df3[df3.companyCode.str.startswith('60')]  # 沪主板
    d5 = df3[df3.companyCode.str.startswith('83')]  # 新三板
    d6 = df3[df3.companyCode.str.startswith('20')]  # 深B
    d7 = df3[df3.companyCode.str.startswith('90')]  # 沪B
    df9 = pd.concat([d1,d2,d3,d4,d5,d6,d7]).reset_index(drop=True)

    df6 = df3[df3.companyCode.str.startswith('58')] # 提取以companyCode以58开头的行 监管部门
    df4 = df3[df3.companyCode.str.startswith('1')] # 提取以companyCode以1开头的行 中介机构
    df7 = df3[df3.companyCode.str.startswith('78')] # 提取以companyCode以78开头的行 拟上市
    df8 = df3.append([df9,df7,df6,df4])
    df8.drop_duplicates(keep = False,inplace = True) # 提取剩余其他数据
    return df9,df7,df6,df4,df8     

2.2 日志点击量分布

"""
单个用户群体日志量分布
注意:需求列表需A,B两列及以上,其中一列为日期列,例如df["date"] = df["A"] ,df["count"] = "1"
"""
def ClickAnalysisByWeek(data1):
    # 上市公司日志量分布
    data1['date'] = pd.to_datetime(data1['date']) # 将数据类型转化为日期类型
    data1 = data1.set_index('date') # 设置date列为索引列
    data1 = data1.resample('w').count() # 以周为单位进行统计累加
    data1["date"] = data1.index.get_level_values(0).values #提取索引列(第-列)值添加为新的一列
    # 时间加减运算,从每周一开始
    from datetime import datetime,timedelta
    data1['date'] = data1['date']-timedelta(days=6)
    data1 = data1.set_index('date') # 将date设置为index
    data1 = data1['count']
    data1 = pd.DataFrame(data1)
    return data1

2.3 每周用户数量

"""
每周用户数量分布
注意:需求列表需三列以上,其中df1['date'] = df1['date1'],df1['companyCode'] = df1["companyCode"],df1['count'] = "1"
"""
def UserAnalysisByWeek(a1):
    # 上市公司
    import numpy as np
    a1['date'] = pd.to_datetime(a1['date']) # 将数据类型转化为日期类型
    a1 = a1.set_index('date') # 设置date列为索引列
    a1 = a1.to_period('w') # 按周统计
    a1["date1"] = a1.index.get_level_values(0).values #提取索引列(第-列)值添加为新的一列
    a1 = a1.groupby(['date1','companyCode'],sort = False).count() # 按周去重
    a1["date"] = a1.index.get_level_values(0).values #提取索引列(第-列)值添加为新的一列
    a1 = a1.groupby(['date'],sort = False).count() # 按周去重
    a1["date1"] = a1.index.get_level_values(0).values #提取索引列(第-列)值添加为新的一列
    a1['date1'] = a1['date1'].astype(np.str) # 格式转化为str
    a1['date1'] = a1['date1'].str[0:10]   # 评论数不一致,截取长短不同,此方法不可取
    a1 = a1.sort_values("date1",ascending = True)  # 按日期从前往后排序
    a1 = a1.set_index('date1') # 设置date列为索引列
    a1 = pd.DataFrame(a1['count'])
    return a1

2.4 累计使用天数

"""
累计使用天数
需求列表需三列以上,其中df1['date'] = df1['date1'],df1['companyCode'] = df1["companyCode"],df1['count'] = "1"
"""
def NumberofDaysUsed(h1):
    h1 = h1.groupby(['date','companyCode'],sort = False).count() # 去除一天中的重复值
    h1 = h1.sort_values('count',ascending = False)
    h1["使用天数"] = h1.index.get_level_values(1).values #提取索引列(第二列)值添加为新的一列
    h1 = h1['使用天数'].value_counts()  # 统计该列所有元素重复次数
    h1 = pd.DataFrame(h1)
    h1 = h1['使用天数'].value_counts()  # 统计该列所有元素重复次数
    h1.sort_index(inplace=True)   # 按索引进行排序
    h1 = pd.DataFrame(h1)
    a1 = h1
    a1['AC'] = '1' 
    a1 = a1.groupby('AC',sort = False).sum()
    print('使用公司数量:',a1)  
    h1 = h1['使用天数']
    h1 = pd.DataFrame(h1)
    return h1