使用 Python 和 Pandas 分析犯罪记录开放数据

从开放数据中,你可以了解一个城市或社区是否安全,并合理避险。

本文借鉴 知乎@王树义 的分析思路,使用 Python 和数据分析包 Pandas 对该数据集进行分析和可视化。

原网址为:https://zhuanlan.zhihu.com/p/58314015?utm_source=qq&utm_medium=social

首先,访问 Denton 开放数据主页,地址是 http://data.cityofdenton.com/ 。搜索 crime 获取数据。

读入 Pandas 库,并使用 Pandas 方法读入 CSV 文件。文件保存在 df 中,并确认文件已经成功读入。

import pandas as pd
df = pd.read_csv('crime_data_20190322.csv')
df.head()
结果图

下面来着重分析一下,都有哪些犯罪类型,每种类型下,又有多少记录。

这里我们使用的是 Pandas 中的 value_counts 函数。它可以帮助我们自动统计某一列中不同类别出现的次数,而且还自动进行排序。为了显示的方便,我们只要求展示前 10 项内容。

value_counts() 是一种查看表格某列中有多少个不同值的快捷方法,并计算每个不同值有在该列中有多少重复值。
value_counts() 是 Series 拥有的方法,一般在 DataFrame 中使用时,需要指定对哪一列或行使用。

iloc 方法是基于索引位来选取数据集, 例如 0:4就是选取 0,1,2,3 这四行,需要注意的是这里是前闭后开集合。

df.crime.value_counts().iloc[:10]
结果图

可以看到位于前几位的犯罪类型分别为:轻微人身攻击,所有其他盗窃案,财产的破坏,醉酒,商店行窃,汽车失窃,使用毒品,诈骗,入室盗窃。

为了更直观查看数据统计结果,我们调用 Pandas 内置的绘图函数 plot ,并且指定绘图类型为“横向条状图”(barh)。

import matplotlib as plt
df.crime.value_counts().iloc[:10].sort_values().plot(kind='barh')

结果为:

结果图

下面,我们着重了解某一种犯罪的情况。因为犯罪类型五花八门,所以我们从中选择一种严重的暴力犯罪——抢劫(Robbery)。

这里,为了后续分析的便利。我们首先把抢劫类型的犯罪单独提炼出来,存储在 robbery 这样一个新的数据框里。同样只展示前几种。

pandas.Series.str.contains() 方法可以通过查询每行是否包含指定字符串进行模糊查询。

robbery = df[df.crime.str.contains('ROBBERY')]; robbery.head()
结果图

我们查看一下“犯罪位置”(locname)类型,以及每种类型对应的记录条目数。

这次,我们使用 groupby 函数,先把犯罪位置进行分类,然后用 size() 函数来查看条目统计。

这里,我们指定排序为从大到小。

groupby('locname').size() 函数可以按照‘locname’这一列进行分组并统计数量。

robbery.shape
robbery.groupby('locname').size().sort_values(ascending=False)
结果图

当然以上代码可以使用value_counts 方法解决。

robbery.locname.value_counts()

结果相同。

根据结果显示,入室抢劫次数最多,在学校、公交车上发生的次数最少。

下面还是用 plot 函数,把结果可视化呈现。

robbery.groupby('locname').size().sort_values(ascending=False).head(10).sort_values().plot(kind='barh')

下一步,我们尝试把分析的粒度做得更加细致——研究一下,哪些街区比较危险。

地址信息都表示为类似“19XX BRINKER RD”这样的方式。把具体地址的后两位隐藏,是为了保护受害者的隐私。

我们如果要统计某一条街道的犯罪数量,就需要把前面的数字忽略,并且按照街道名称加总。

这个处理起来,并不困难,只要用正则表达式即可。

正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑.

regex = r"\d+XX\s(?P<street>.*)"
subst = "\\g<street>"

这里,我们用括号把需要保留的内容,赋值为 street 分组。然后替换的时候,只保留这个分组的信息。于是前面的具体地址数字就忽略了。

调用 Pandas 的 str.replace 函数,我们可以让它自动将每一个地址都进行解析替换,并且把结果存入到了一个新的列名称,即 street

robbery["street"] = robbery.publicadress.str.replace(regex, subst)

可以看到在 DataFrame 的最后一列是简化的街道。

依然按照前面的方法,我们分组统计每一条街道上的犯罪数量,并且进行排序。

robbery.groupby('street').size().sort_values(ascending=False).head(10)

看来,大学西道(W University DR)抢劫频发,没事儿最好少去瞎转悠。

注意,我们其实是在分析10年的犯罪信息汇总。如果更进一步,想要利用时间数据,进行切分,我们就得把日期信息做一下转换处理。

我们从 dateutil 里面的 parser 模块,载入全部内容。

from dateutil.parser import *

下面,我们抽取年度信息。因为目前的日期时间列(incidentdatetime)是个字符串,因此我们可以直接用 parse 函数解析它,并且抽取其中的年份(year)项。

robbery["year"] = robbery.incidentdatetime.apply(lambda x: parse(x).year)

apply 函数是pandas里面所有函数中自由度最高的函数。该函数如下:

DataFrame.apply(func, axis=0, broadcast=False, raw=False, reduce=None, args=(), **kwds)

该函数最有用的是第一个参数,这个参数是函数,相当于 C/C++ 的函数指针。

这个函数需要自己实现,函数的传入参数根据 axis 来定,比如 axis = 1,就会把一行数据作为 Series 的数据结构传入给自己实现的函数中,我们在函数中实现对 Series 不同属性之间的计算,返回一个结果,则 apply 函数会自动遍历每一个DataFrame 的数据,最后将所有结果组合成一个 Series 数据结构并返回。

字符串转日期

DateUtil.parse方法会自动识别一些常用格式,包括:

  1. yyyy-MM-dd HH:mm:ss

  2. yyyy-MM-dd

  3. HH:mm:ss

  4. yyyy-MM-dd HH:mm

  5. yyyy-MM-dd HH:mm:ss.SSS

更多关于此方法的介绍见 https://www.cnblogs.com/mr-wuxiansheng/p/7787296.html

以下是程序运行的结果,可以看到成功列出了 年、月、日。

我们先按照年度来看看抢劫犯罪数量的变化趋势。

robbery.groupby('year').size()

注意这里,数量最少的是 2019 年。看似是很喜人的变化。可惜我们分析数据的时候,一定要留心这种细节。

我们读取的数据,统计时间截止到 2019 年的 3 月初。因此,2019年数据并不全。

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