你获得了一些想要分析的数据,从哪里开始呢?
许多习惯于图形环境的人可能会默认使用电子表格工具,但还有另一种方式,只需稍加努力,就可以证明它更快、更有效。而且你不需要成为统计建模语言或大数据工具集的专家,就能利用这些工具。
我说的是 Linux 命令行。只需使用一些你可能已经在计算机上安装的工具,你就可以在不离开终端的情况下了解大量关于数据集的信息。长期的 Linux 用户当然会嘲笑——他们多年来一直在使用这些工具来解析日志和理解配置工具。但对于 Linux 新手来说,你已经掌握了一整套数据分析工具包这一发现,可能会是一个令人欣慰的惊喜。
这些工具大多不仅限于 Linux。它们大多可以追溯到 Unix 时代,其他类 Unix 操作系统的用户可能已经安装了它们,或者可以轻松地安装它们。许多是 GNU Coreutils 包的一部分,而一些是单独维护的,经过一些努力,你甚至可以在 Windows 上使用它们。
让我们试用一些用于数据分析的简单开源工具,看看它们是如何工作的!如果你想跟随这些示例,请下载这个 示例数据文件,它来自 GitHub,是一个 CSV(逗号分隔值)列表,其中包含我们在 1 月份发布到 Opensource.com 的文章。
head 和 tail
首先,让我们从了解文件开始。它包含什么?它的格式是什么样的?你可以使用 cat 命令在终端中显示文件,但如果你要处理的文件超过几十行,那对你没有多大帮助。
输入 head 和 tail。它们都是用于显示文件顶部或底部指定行数的实用程序。如果你没有指定要查看的行数,你将获得 10 行。让我们用我们的文件试一下。
$ tail -n 3 jan2017articles.csv
02 Jan 2017,Article,Scott Nesbitt,3 tips for effectively using wikis for documentation,1,/article/17/1/tips-using-wiki-documentation,"Documentation, Wiki",710
02 Jan 2017,Article,Jen Wike Huger,The Opensource.com preview for January,0,/article/17/1/editorial-preview-january,,358
02 Jan 2017,Poll,Jason Baker,What is your open source New Year's resolution?,1,/poll/17/1/what-your-open-source-new-years-resolution,,186
查看最后三行,我可以立即挑出日期、作者姓名、标题和其他一些信息。但我不知道每一列是什么。让我们看看文件的顶部,看看它是否有标题来解释每一列的含义。
$ head -n 1 jan2017articles.csv
Post date,Content type,Author,Title,Comment count,Path,Tags,Word count
好的,现在一切都说得通了。看起来我们得到了一个文章列表,其中包含文章的发布日期、每篇文章的内容类型、作者、标题、评论数、相对 URL、每篇文章的标签以及字数。
wc
这太好了,但这个文件有多大?我们是在讨论几十篇要分析的文章,还是数百篇,甚至数千篇?wc 命令可以帮助解决这个问题。wc 是 "word count"(字数统计)的缩写,可以计算文件中的字节数、字符数、字数或行数。在我们的例子中,我们想知道行数。
$ wc -l jan2017articles.csv
93 jan2017articles.csv
好了,就是这样。这个文件中有 93 行;因为我们知道第一行包含标题,所以我们可以推断这是一个包含 92 篇文章的列表。
grep
好了,现在让我们问自己:在这 92 篇文章中,有多少篇是关于安全主题的?为了我们的目的,让我们假设我们对文章中任何地方提到安全性的文章感兴趣,无论是在标题、标签列表还是其他地方。grep 工具可以帮助我们解决这个问题。使用 grep,你可以搜索文件或其他输入中特定模式的字符。grep 是一个非常强大的工具,这要归功于你可以构建的 正则表达式,它可以匹配非常精确的模式。但现在,让我们只搜索一个简单的字符串。
$ grep -i "security" jan2017articles.csv
30 Jan 2017,Article,Tiberius Hefflin,4 ways to improve your security online right now,3,/article/17/1/4-ways-improve-your-online-security,Security and encryption,1242
28 Jan 2017,Article,Subhashish Panigrahi,How communities in India support privacy and software freedom,0,/article/17/1/how-communities-india-support-privacy-software-freedom,Security and encryption,453
27 Jan 2017,Article,Alan Smithee,Data Privacy Day 2017: Solutions for everyday privacy,5,/article/17/1/every-day-privacy,"Big data, Security and encryption",1424
04 Jan 2017,Article,Daniel J Walsh,50 ways to avoid getting hacked in 2017,14,/article/17/1/yearbook-50-ways-avoid-getting-hacked,"Yearbook, 2016 Open Source Yearbook, Security and encryption, Containers, Docker, Linux",2143
我们使用的格式是 grep,后跟 -i 标志(告诉 grep 不要区分大小写),后跟我们要搜索的模式,然后是我们要搜索的文件。看起来我们上个月有四篇与安全相关的文章。但假设我们得到了一个比我们容易统计的列表长得多的列表。使用 管道,我们可以将 grep 与我们刚才学到的 wc 命令结合起来,以获得提及安全性的总行数。
$ grep -i "security" jan2017articles.csv | wc -l
4
在本例中,wc 接受了 grep 命令的输出,并将其用作其输入,而无需担心先将其保存到任何地方。这就是为什么管道输入和输出,特别是当与一些 shell 脚本 结合使用时,使得终端成为数据分析的强大工具。
tr
对于许多分析场景来说,CSV 文件是一个非常有用的格式,但如果你需要将文件转换为不同的格式以在不同的应用程序中使用呢?也许你需要制表符分隔符而不是逗号,或者也许你想将它们更改为一些 HTML,以便你可以在表格中使用数据输出。tr 命令可以通过从一种类型的字符转换为另一种类型的字符来帮助你解决这个问题。与其他示例一样,你也可以将输入和输出通过管道传输到此命令。
让我们尝试另一个多部分示例,创建一个仅包含 1 月 20 日发布的文章的 TSV(制表符分隔值)文件。
$ grep "20 Jan 2017" jan2017articles.csv | tr ',' '\t' > jan20only.tsv
这是怎么回事?首先,我们使用 grep 搜索了相关日期。我们将此输出通过管道传输到 tr 命令,我们用它来将逗号替换为制表符(用 '\t' 表示)。但它去了哪里?好吧,> 字符将输出重定向到我们的新文件,而不是屏幕。所有这些工作都在一个命令序列中完成。然后我们可以验证 jan20only.tsv 文件是否包含我们期望的数据。
$ cat jan20only.tsv
20 Jan 2017 Article Kushal Das 5 ways to expand your project's contributor base 2 /article/17/1/expand-project-contributor-base Getting started 690
20 Jan 2017 Article D Ruth Bavousett How to write web apps in R with Shiny 2 /article/17/1/writing-new-web-apps-shiny Web development 218
20 Jan 2017 Article Jason Baker "Top 5: Shell scripting the Cinnamon Linux desktop environment and more" 0 /article/17/1/top-5-january-20 Top 5 214
20 Jan 2017 Article Tracy Miranda How is your community promoting diversity? 1 /article/17/1/take-action-diversity-tech Diversity and inclusion 1007
sort
如果我们想了解有关特定列的更多详细信息怎么办?在我们的新文章列表中,哪篇文章最长?让我们以上面的最后一个示例为基础。现在我们有了一个仅包含 1 月 20 日文章的列表,我们可以使用 sort 命令按字数统计列进行排序。当然,我们严格来说不需要一个中间文件;我们可以通过管道传输上一个命令的输出。但有时将长步骤分解为较小的步骤,而不是创建巨大的命令链,会更容易。
$ sort -nr -t$'\t' -k8 jan20only.tsv | head -n 1
20 Jan 2017 Article Tracy Miranda How is your community promoting diversity? 1 /article/17/1/take-action-diversity-tech Diversity and inclusion 1007
这是另一个很长的例子,让我们分解一下发生了什么。首先,我们使用 sort 命令按字数排序。-nr 选项告诉 sort 进行数字排序,并按相反的顺序(从大到小)返回结果。接下来的 -t$'\t' 告诉 sort 分隔符是制表符 ('\t')。(你可以 在这里 阅读你为什么需要美元符号;简而言之,它是告诉 shell 这是一个需要处理的字符串,以便将 \n 转换为实际的制表符)。命令的 -k8 部分告诉 sort 使用第八列,这在我们示例中是字数统计列。
最后,整个输出通过管道传输到 head,并指示只显示第一行,这是我们的结果,即此文件中字数最多的文章。
sed
你可能想要选择文件的特定行。sed,是流编辑器的缩写,是一种方法。如果你想合并多个都有标题的文件怎么办?你只需要一组标题出现在整个文件中,因此你需要一种方法来删除多余的标题。或者如果你只想获取特定范围的行怎么办?sed 是你的工具。它也是批量查找和替换文件的绝佳方法。
让我们从文章列表中创建一个没有标题的新文件,适合与其他文件组合(例如,如果我每个月都有一个不同的文件,并且想将它们放在一起)。
$ sed '1 d' jan2017articles.csv > jan17no_headers.csv
'1 d' 选项告诉 sed 删除第一行。sed 的功能远不止于此,我建议进一步阅读它的 替换功能。
cut
如果我想删除一列而不是删除一行怎么办?如果我只想挑选一列怎么办?让我们为上面构建的示例创建一个新的作者列表。
$ cut -d',' -f3 jan17no_headers.csv > authors.txt
在这个简单的例子中,我们用 -d',' 告诉 cut 这是一个逗号分隔的文件,我们想要第三列 (-f3),并将输出发送到一个名为 authors.txt 的新文件。
uniq
上一个例子给我们留下了一个作者列表,但是,这个列表里有多少个不重复的作者呢?每个作者写了多少篇文章?现在请使用 uniq。有了 uniq,你可以很容易地找到答案。让我们对文件进行排序,找出唯一值,然后输出一个文件,其中包含每个作者撰写的文章数量的计数。
sort authors.txt | uniq -c > authors-sorted.txt
浏览一下文件,我们现在可以看到每个作者写了多少篇文章。让我们只看最后三行来确保它正常工作。
$ tail -n3 authors-sorted.txt
1 Tracy Miranda
1 Veer Muchandi
3 VM (Vicky) Brasseur
awk
今天我们再来看看命令行数据分析工具箱中的另一个工具,awk。 awk 是我介绍得不够充分的工具之一;它实际上是一个强大的工具,值得深入探索。它也是一个很棒的替换工具,但功能远不止于此。让我们回到之前制作的仅包含 1 月 20 日文章的 TSV 文件,并使用它创建一个新列表,其中仅包含这些文章的作者,以及每个作者撰写的字数。
$ awk -F "\t" '{print $3 " " $NF}' jan20only.tsv
Kushal Das 690
D Ruth Bavousett 218
Jason Baker 214
Tracy Miranda 1007
这是怎么回事?传递给 awk 的 -F "\t" 只是告诉它我们正在处理制表符分隔的数据。在花括号内,我们实际上是在告诉 awk 执行一小段代码。我们告诉它打印第三列,使用 $3,然后打印最后一列,使用 $NF(“字段数”),并在它们之间放置两个空格,使其更易于阅读。
所以呢?难道我们不能在电子表格中更快地完成所有这些操作,或者在某些情况下直接查看文件吗?当然可以!现在停下来想象一下,不是处理一个 93 行的文件,而是处理一个 93,000 行甚至更大的文件。你的电子表格程序能在不崩溃或显著降低速度的情况下加载它吗?或者想象一下,不是处理一个包含一个月文章的文件,而是处理过去七个月每个月都不同的文件。突然间,电子表格不再是处理数据的最佳选择,但你还没有完全进入需要真正的大数据工具来处理数据集的领域。
你可以选择将文件加载到数据库工具中并在那里处理数据。但那是正确的选择吗?这可能有点过头了。如果你只是在检查数据以了解其包含的内容呢?使用这些简单的工具和一些脚本来递归遍历目录,你可以轻松地处理大量数据。定期处理数据的专业人士和业余爱好者都应该花一些时间学习这些和其他命令行数据分析工具。
此介绍仅触及了每个工具的表面。它们的功能远比这些简单的例子所暗示的要强大得多,这就是为什么大多数工具都写了大量的书籍。我希望你花时间阅读手册页,在搜索引擎中做一些工作,或者拿起一本书,更多地了解你手头拥有的这一有趣的工具套件。
11 条评论