从未这样玩过!第一次使用 Python 分析 14 亿条数据

栏目: Python · 发布时间: 5年前

内容简介:来源:

从未这样玩过!第一次使用  <a href='https://www.codercto.com/topics/20097.html'>Python</a>  分析 14 亿条数据

这是恋习Python推荐的第 121 篇好文

来源: 掘金翻译计划

作者: Steve Stagg

你用 Python 处理过的最大数据集有多大?我想大概不会超过上亿条吧,今天分享一个用 Python 处理分析 14 亿条数据的案

这份 14 亿条数据集来自 Google Books ,由 Google Ngram viewer 生成,根据书本印刷的每一个年份,记录了一个特定单词或词组在谷歌图书的使用量。数据集中有成千上百万的书,时间上涵盖了从 16 世纪到 2008 年。可以绘制出单词使用量随时间的变化,比如查询「Python 」在历史中出现的频率。

从未这样玩过!第一次使用 Python 分析 14 亿条数据

从未这样玩过!第一次使用 Python 分析 14 亿条数据

数据集可以免费从这里下载:

http://storage.googleapis.com/books/ngrams/books/datasetsv2.html

下面使用 Python 的 PyTubes 数据库来加载上面的数据集,然后分析生成上面这样一张图。PyTubes 是一个专门用来加载大数据源的库。

1-gram 的数据集在硬盘上可以展开成为 27 Gb 的数据,这在读入 python 时是一个很大的数据量级。Python可以轻易地一次性地处理千兆的数据,但是当数据是损坏的和已加工的,速度就会变慢而且内存效率也会变低。

总的来说,这 14 亿条数据(1,430,727,243)分散在 38 个源文件中,一共有 2 千 4 百万个(24,359,460)单词(和词性标注,见下方),计算自 1505 年至 2008 年。

当处理 10 亿行数据时,速度会很快变慢。并且原生 Python 并没有处理这方面数据的优化。幸运的是,numpy 真的很擅长处理大体量数据。使用一些简单的技巧,我们可以使用 numpy 让这个分析变得可行。

在 python/numpy 中处理字符串很复杂。字符串在 python 中的内存开销是很显著的,并且 numpy 只能够处理长度已知而且固定的字符串。基于这种情况,大多数的单词有不同的长度,因此这并不理想。

加载数据集

下面所有的代码/例子都是运行在  8 GB 内存 的 2016 年的 Macbook Pro。如果硬件或云实例有更好的 ram 配置,表现会更好。

1-gram 的数据是以 tab 键分割的形式储存在文件中,看起来如下:

1Python 1587 4 2
2Python 1621 1 1
3Python 1651 2 2
4Python 1659 1 1

每一条数据包含下面几个字段:

11. Word
22. Year of Publication
33. Total number of times the word was seen
44. Total number of books containing the word

为了按照要求生成图表,我们只需要知道这些信息,也就是:

11. 这个单词是我们感兴趣的?
22. 发布的年份
33. 单词使用的总次数

通过提取这些信息,处理不同长度的字符串数据的额外消耗被忽略掉了,但是我们仍然需要对比不同字符串的数值来区分哪些行数据是有我们感兴趣的字段的。这就是 pytubes 可以做的工作:

 1import tubes
2
3FILES = glob.glob(path.expanduser("~/src/data/ngrams/1gram/googlebooks*"))
4WORD = "Python"
5one_grams_tube = (tubes.Each(FILES)
6 .read_files()
7 .split()
8 .tsv(headers=False)
9 .multi(lambda row: (
10 row.get(0).equals(WORD.encode('utf-8')),
11 row.get(1).to(int),
12 row.get(2).to(int)
13 ))
14)

差不多 170 秒(3 分钟)之后,  one grams_ 是一个 numpy 数组,里面包含差不多 14 亿行数据,看起来像这样(添加表头部为了说明):

 1╒═══════════╤════════╤═════════╕
2│ Is_Word │ Year │ Count │
3╞═══════════╪════════╪═════════╡
4017992
5├───────────┼────────┼─────────┤
6018041
7├───────────┼────────┼─────────┤
8018051
9├───────────┼────────┼─────────┤
10018111
11├───────────┼────────┼─────────┤
1201820...
13╘═══════════╧════════╧═════════╛

下面就可以开始分析数据了。

每年单词总使用量

谷歌展示了每一个单词出现的百分比(某个单词在这一年出现的次数/所有单词在这一年出现的总数),这比仅仅计算原单词更有用。为了计算这个百分比,我们需要知道单词总量的数目是多少。

幸运的是,numpy让这个变得十分简单:

 1last_year = 2008
2YEAR_COL = '1'
3COUNT_COL = '2'
4year_totals, bins = np.histogram(
5 one_grams[YEAR_COL],
6 density=False,
7 range=(0, last_year+1),
8 bins=last_year + 1,
9 weights=one_grams[COUNT_COL]
10)

绘制出这个图来展示谷歌每年收集了多少单词:

从未这样玩过!第一次使用 Python 分析 14 亿条数据
img

很清楚的是在 1800 年之前,数据总量下降很迅速,因此这回曲解最终结果,并且会隐藏掉我们感兴趣的模式。为了避免这个问题,我们只导入 1800 年以后的数据:

 1one_grams_tube = (tubes.Each(FILES)
2 .read_files()
3 .split()
4 .tsv(headers=False)
5 .skip_unless(lambda row: row.get(1).to(int).gt(1799))
6 .multi(lambda row: (
7 row.get(0).equals(word.encode('utf-8')),
8 row.get(1).to(int),
9 row.get(2).to(int)
10 ))
11)

这返回了 13 亿行数据(1800 年以前只有 3.7% 的的占比)

从未这样玩过!第一次使用 Python 分析 14 亿条数据
img

Python 在每年占比百分数

获得 python 在每年的占比百分数现在就特别的简单了。

使用一个简单的技巧,创建基于年份的数组,2008 个元素长度意味着每一年的索引等于年份的数字,因此,举个例子,1995 就只是获取 1995 年的元素的问题了。

这都不值得使用 numpy 来操作:

1word_rows = one_grams[IS_WORD_COL]
2word_counts = np.zeros(last_year+1)
3for _, year, count in one_grams[word_rows]:
4 word_counts[year] += (100*count) / year_totals[year]

绘制出 word_counts 的结果:

从未这样玩过!第一次使用 Python 分析 14 亿条数据
img

形状看起来和谷歌的版本差不多

从未这样玩过!第一次使用 Python 分析 14 亿条数据
img

实际的占比百分数并不匹配,我认为是因为下载的数据集,它包含的用词方式不一样(比如:Python_VERB)。这个数据集在 google page 中解释的并不是很好,并且引起了几个问题:

  • 人们是如何将 Python 当做动词使用的?

  • 'Python' 的计算总量是否包含 'Python_VERB'?等

幸运的是,我们都清楚我使用的方法生成了一个与谷歌很像的图标,相关的趋势都没有被影响,因此对于这个探索,我并不打算尝试去修复。

性能

谷歌生成图片在 1 秒钟左右,相较于这个脚本的 8 分钟,这也是合理的。谷歌的单词计算的后台会从明显的准备好的数据集视图中产生作用。

举个例子,提前计算好前一年的单词使用总量并且把它存在一个单独的查找表会显著的节省时间。同样的,将单词使用量保存在单独的数据库/文件中,然后建立第一列的索引,会消减掉几乎所有的处理时间。

这次探索  确实 展示了,使用 numpy 和 初出茅庐的 pytubes 以及标准的商用硬件和 Python,在合理的时间内从十亿行数据的数据集中加载,处理和提取任意的统计信息是可行的,

Python,Pascal 和 Perl 对比

为了用一个稍微更复杂的例子来证明这个概念,我决定比较一下三个相关提及的编程语言: Python,Pascal, 和  Perl.

源数据比较嘈杂(它包含了所有使用过的英文单词,不仅仅是编程语言的提及,并且,比如,python 也有非技术方面的含义!),为了这方面的调整, 我们做了两个事情:

1. 只有首字母大写的名字形式能被匹配(Python,不是 python)

2. 每一个语言的提及总数已经被转换到了从 1800 年到 1960 年的百分比平均数,考虑到 Pascal 在 1970 年第一次被提及,这应该有一个合理的基准线。

结果:

从未这样玩过!第一次使用 Python 分析 14 亿条数据
img

对比谷歌 (没有任何的基准线调整):

从未这样玩过!第一次使用 Python 分析 14 亿条数据
img

运行时间: 只有 10 分钟多一点。

以上就是用 Python 处理大数据的一次尝试,源代码可以在这里获取:

https://gist.github.com/stestagg

觉得不错,点个在看呗!


以上所述就是小编给大家介绍的《从未这样玩过!第一次使用 Python 分析 14 亿条数据》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

智能家居:商业模式+案例分析+应用实战

智能家居:商业模式+案例分析+应用实战

陈国嘉 / 人民邮电出版社 / 2016-4 / 49.80元

作为万物互联的关键一环,智能家居的出现和普及已经势不可当,以移动互联网为核心的新技术正在重构智能家居。只有成为智能家居行业的先行者,才能抢占“风口”。 《智能家居:商业模式+案例分析+应用实战》紧扣“智能家居”,从3个方面进行专业、深层次的讲解。首要方面是基础篇,从智能家居的发展现状、产业链、商业分析、抢占入口等方面进行阐述,让读者对智能家居有个初步的认识;第二个方面是技术篇,从智能家居的控......一起来看看 《智能家居:商业模式+案例分析+应用实战》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具