美文网首页
14_1从Bitly获取1.USA.gov数据

14_1从Bitly获取1.USA.gov数据

作者: 弦好想断 | 来源:发表于2020-05-11 10:19 被阅读0次

    纯python进行时区计数

    import pandas as pd
    import numpy as np
    import json
    path = 'example.txt'
    open(path).readline()#只读取文件的第一行
    open(path).readlines()#读取文件的所有行
    
    records = [json.loads(line) for line in open(path)]
    records[0]
    
    #找到数据中最常出现的‘tz’时区
    time_zones = [rec['tz'] for rec in records if 'tz' in rec]#这里要考虑并不是索引记录都有时区字段
    time_zones[:10]
    

    两种计数方法,认真理解!

    def get_counts(sequence):
        counts = {}
        for x in sequence:
            if x in counts:
                counts[x]+=1
            else:
                counts[x]=1
        return counts
    counts = get_counts(time_zones)
    counts
    from collections import defaultdict
    def get_counts2(sequence):
        counts = defaultdict(int)#值将会初始化为0
        for x in sequence:
            counts[x]+=1
        return counts
    counts2 = get_counts2(time_zones)
    counts2
    
    def top_counts(counts2,n=10):
        value_key_pairs = [(value,key) for key,value in counts2.items()]
        value_key_pairs.sort()
        return value_key_pairs[-n:]
    top_counts(counts)
    

    第二种方法,认真理解

    from collections import Counter
    counts = Counter(time_zones)
    counts.most_common(10)
    

    使用pandas进行时区计数

    frame = pd.DataFrame(records)
    frame.info()
    
    frame.head()
    
    frame['tz'].value_counts()[:10]
    

    数据清理
    用fillna方法替换缺失值,为空字符串使用布尔索引:

    clean_tz = frame['tz'].fillna('missing')
    clean_tz[clean_tz==''] = 'Unknown'
    tz_counts = clean_tz.value_counts()
    tz_counts[:10]#可以看出结果与上面不同
    

    这里画的是时区计数的柱状图

    import seaborn as sns
    subset = tz_counts[:10]
    sns.barplot(x=subset.values,y=subset.index)
    

    a列包含了网址缩短的浏览器、设备或引用的信息:

    frame['a'][1]
    'GoogleMaps/RochesterNY'
    frame['a'][50]
    'Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2'
    frame['a'][51][:50]#很长的一行,这里选前50个值
    'Mozilla/5.0 (Linux; U; Android 2.2.2; en-us; LG-P9'
    #分离字符串中的第一个标记
    results = pd.Series([x.split()[0] for x in frame['a'].dropna()])
    results[:5]
    0               Mozilla/5.0
    1    GoogleMaps/RochesterNY
    2               Mozilla/4.0
    3               Mozilla/5.0
    4               Mozilla/5.0
    dtype: object
    results.value_counts()[:8]
    Mozilla/5.0                 2594
    Mozilla/4.0                  601
    GoogleMaps/RochesterNY       121
    Opera/9.80                    34
    TEST_INTERNET_AGENT           24
    GoogleProducer                21
    Mozilla/6.0                    5
    BlackBerry8520/5.0.0.681       4
    dtype: int64
    

    将时区计数多的时区记录分解为Windows和非Windows用户。
    想计算一个代表每一行是否是Windows的值:

    cframe = frame[frame.a.notnull()]
    cframe.loc[:,'os']=np.where(cframe.loc[:,'a'].str.contains('Windows'),'Windows','Not Windows')
    #where的用法,满足条件(condition),输出x,不满足输出y。
    cframe.head()
    
    agg_counts = cframe.groupby(['tz','os']).size().unstack().fillna(0)
    #分组后在将内层索引拆分为行标签
    agg_counts.head()
    

    选出总体计数最高的时区

    #选出总体计数最高的时区
    indexer = agg_counts.sum(1).argsort()#返回数组从小到大的索引值
    indexer[:10]
    tz
                                      24
    Africa/Cairo                      20
    Africa/Casablanca                 21
    Africa/Ceuta                      92
    Africa/Johannesburg               87
    Africa/Lusaka                     53
    America/Anchorage                 54
    America/Argentina/Buenos_Aires    57
    America/Argentina/Cordoba         26
    America/Argentina/Mendoza         55
    dtype: int64
    
    #使用take按顺序选出行,之后再对最后10行(也就是最大的10个值)进行切片
    count_subset = agg_counts.take(indexer[-10:])
    count_subset[:]
    

    有一个便捷的的方法叫做nlargest,可以做同样的事情:

    agg_counts.sum(1).nlargest(10)
    
    agg_counts.sum(1).sort_values()[-10:]
    
    count_subset = count_subset.stack()#堆叠进来
    count_subset.name = 'total'
    count_subset = count_subset.reset_index()#重置索引,把分组索引拿进来别称列标签
    count_subset[:10]
    
    sns.barplot(x='total',y ='tz',hue='os',data=count_subset)
    
    def norm_total(group):
        group['normed_total']=group.total/group.total.sum()#计算相对百分比
        return group
    results = count_subset.groupby('tz').apply(norm_total)
    sns.barplot(x='normed_total',y='tz',hue='os',data=results)
    
    #用transform更为高效的计算归一化之和
    g = count_subset.groupby('tz')
    result2 = count_subset.total/g.total.transform('sum')
    sns.barplot(x=result2,y='tz',hue='os',data=results)
    

    很简单的一个案例,几个细节:unstack(),where(),for循环后面的if条件判断,defaultdict()的应用,json文件的读取,nlargest(),argsort(),take()等方法要熟悉。

    相关文章

      网友评论

          本文标题:14_1从Bitly获取1.USA.gov数据

          本文链接:https://www.haomeiwen.com/subject/szbynhtx.html