数据分析案例(USA.gov)

来自Bitly的USA.gov数据

2011年,URL缩短服务Bitly跟美国政府网站USA.gov合作,提供了一份从生成.gov或.mil短链接的用户那里收集来的匿名数据。

以每小时快照为例,文件中各行的格式为JSON:

读取文件

使用json模块及其loads函数逐行加载已经下载好的数据文件

import json 

records = [json.loads(line) for line in open(path)]
部分加载数据

用纯Python代码对时区进行计数

求该数据集中常出现的是哪个时区(即tz字段)

time_zones = [rec['tz'] for rec in records] 
错误命令

因为并不是所有记录都有时区字段

time_zones = [rec['tz'] for rec in records if 'tz' in rec]
取数据集中出现的前10个时区

对时区进行计数,这里介绍两个办法:一个较难(只使用标准Python库),另一个较简单(使用pandas)

计数的办法之一是在遍历时区的过程中将计数值保存在字典中

def get_counts(sequence):    
    counts = {}
    for x in sequence:
        if x in counts:
            counts[x] += 1
        else:
            counts[x] = 1
    return counts

from collections import defaultdict
def get_counts2(sequence):
    counts = defaultdict(int)  # values will initialize to 0 
    for x in sequence:
        counts[x] += 1
    return counts

defaultdictt的作用是在于,当字典里的key不存在但被查找时,返回的不是keyError而是一个默认值(返回的是工厂函数的默认值,比如list对应[ ],str对应的是空字符串,set对应set( ),int对应0)

统计纽约出现的次数

要得到前10位的时区及其计数值

def top_counts(count_dict, n=10):
    value_key_pairs = [(count, tz) for tz, count in count_dict.items()]
    value_key_pairs.sort()
    return value_key_pairs[-n:]
前10位的时区及其计数值

collections.Counter类,它可以使这项工作更简单

from collections import Counter

counts = Counter(time_zones)

counts.most_common(10) 
前10位的时区及其计数值

用pandas对时区进行计数

import pandas as pd

frame = pd.DataFrame(records)
frame.info()
生成Pandas数据
部分数据查看

对Series使用value_counts方法

tz_counts = frame['tz'].value_counts()
计数后取前十

可以用matplotlib可视化这个数据。为此,我们先给记录中未知或缺失的时区填上一个替代值。fillna函数可以替换缺失值(NA),而未知值(空字符串)则可以通过布尔型数组索引加以替换

clean_tz = frame['tz'].fillna('Missing')

clean_tz[clean_tz == ''] = 'Unknown'

tz_counts = clean_tz.value_counts()
画图之前进行数据清理

用seaborn包创建水平柱状图

import seaborn as sns

subset = tz_counts[:10]
sns.barplot(y=subset.index, x=subset.values)
创建水平柱状图

a字段含有执行URL短缩操作的浏览器、设备、应用程序的相关信息

抽样检查

将这些”agent”字符串中的所有信息都解析出来是一件挺郁闷的工作。一种策略是将这种字符串的第一节(与浏览器大致对应)分离出来并得到另外一份用户行为摘要

results = pd.Series([x.split()[0] for x in frame.a.dropna()])
与浏览器大致对应的数量统计

假设想按Windows和非Windows用户对时区统计信息进行分解。为了简单起见,我们假定只要agent字符串中含有”Windows”就认为该用户为Windows用户。由于有的agent缺失,所以首先将它们从数据中移除

cframe = frame[frame.a.notnull()]

然后计算出各行是否含有Windows的值

cframe['os'] = np.where(cframe['a'].str.contains('Windows'),  'Windows', 'Not Windows')
计算前5行是否含有Windows的值

根据时区和新得到的操作系统列表对数据进行分组

by_tz_os = cframe.groupby(['tz', 'os'])

分组计数,类似于value_counts函数,可以用size来计算。并利用unstack对计数结果进行重塑

agg_counts = by_tz_os.size().unstack().fillna(0)
不同时区内使用操作系统的对比

根据agg_counts中的行数构造了一个间接索引数组

indexer = agg_counts.sum(1).argsort()
构造间接索引数组

通过take按照这个顺序截取了后10行大值

count_subset = agg_counts.take(indexer[-10:])
take

pandas有一个简便方法nlargest,可以做同样的工作

nlargest

传递一个额外参数到seaborn的barpolt函数,来画一个堆积条形图

count_subset = count_subset.stack()

count_subset.name = 'total'

count_subset = count_subset.reset_index()

count_subset[:10] 
堆积条形图

这张图不容易看出Windows用户在小分组中的相对比例,因此标准化分组百分比之和为1

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)
标准化分组百分比

还可以用groupby的transform方法,更高效的计算标准化的和

g = count_subset.groupby('tz')

results2 = count_subset.total / g.total.transform('sum')
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 230,825评论 6 546
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,814评论 3 429
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 178,980评论 0 384
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 64,064评论 1 319
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,779评论 6 414
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 56,109评论 1 330
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 44,099评论 3 450
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 43,287评论 0 291
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,799评论 1 338
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,515评论 3 361
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,750评论 1 375
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 39,221评论 5 365
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,933评论 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 35,327评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,667评论 1 296
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,492评论 3 400
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,703评论 2 380

推荐阅读更多精彩内容