个性化阅读
专注于IT技术分析

8个有用的Shell数据科学命令

本文概述

在许多情况下, 你需要快速分析, 修改和处理数量和大小较大的文件。但是, 文件通常是基于文本的逗号分隔值(CSV)文件。使用标准电子表格应用程序(例如Excel, LibreOffice或OpenOffice)打开它们会使计算机的内存过载。另外, 由于一些意外的文件异常, 一批处理大量文件通常在几个小时后失败。

你不可避免地会在冻结屏幕, 重新启动和长时间等待上花费大量时间。

但是, 大多数这些任务可以用几行代码来完成。而且, 熟悉一些简单的shell命令行可以大大节省时间并减少挫败感。

这篇文章将概述我几乎每天都使用的一些shell命令。希望你觉得它们有用。

shell数据科学

快速笔记

请注意, shell的类型不同(bash, zsh等), 其中bash shell最为常见, 因为它是OS X和主要linux发行版上的默认shell。 Zsh(还有Oh My Zsh)是一种流行且功能强大的替代方案。此博客文章中包含的shell命令已经在OS X(macOS)上的bash上进行了测试, 并且可以与其他shell和环境一起使用。

以下所有示例均基于UCI机器学习存储库中的成人数据集, 也称为”普查收入”数据集, 可在此处获取。此数据集通常用于根据普查数据预测收入是否超过\ $ 50K /年。拥有48842行和14个属性, 到目前为止, 它并不是一个很大的数据集, 但足以说明这些示例。尽管数据以.data扩展名存储, 但它是格式正确的CSV文件。随时下载数据集以继续学习!

用wc计数

给定一个基于文本的新文件, 你想知道它包含多少行。这可以通过单词count wc -l命令来完成:

$ wc -l adult.data
  32562 adult.data

告诉你Adult.data文件包含32562行。 -l标志告诉wc计算行数。但是你也可以使用wc代替-w标志来计数单词。

$ wc -w adult.data
  488415 adult.data

adult.data文件包含近50万个字。

通过使用简单的ls -l命令的输出作为wc的输入, wc命令还可以计算目录中的文件数。使用管道符号|将命令的输出用作另一个命令的输入是一种有用的shell模式, 称为流水线。在整个文章中, 你将在几个示例中看到它。

假设现在你有一个包含许多文件的文件夹。以下命令将准确告诉你它包含多少个文件:

$ ls -l <folder> | wc -l
 508

如果你开始添加通配符和子文件夹, 则wc还有许多其他应用程序。

让我们回到你的adult.data文件, 并使用head命令查看第一行。默认情况下, head输出10行, 你可以使用-n标志将输出限制为前2行。

$ head -n 2 adult.data
39, State-gov, 77516, Bachelors, 13, Never-married, Adm-clerical, Not-in-family, White, Male, 2174, 0, 40, United-States, <=50K
50, Self-emp-not-inc, 83311, Bachelors, 13, Married-civ-spouse, Exec-managerial, Husband, White, Male, 0, 0, 13, United-States, <=50K

并且你注意到该文件没有标题行。列名不在文件内。你可以通过使用cat命令连接两个文件来添加该标题行。

用cat连接文件

cat命令将文件的内容打印到标准输出(也就是你的终端)上。它也可以用来连接一系列文件。命令cat file_1.csv file_2.csv> target_file.csv会将file_1.csv和file_2.csv的内容合并到target_file.csv中, 并在file_1.csv的末尾添加file_2.csv。

头文件不在原始数据集中, 你需要创建它。为此, 你将以逗号分隔的列名列表回显到header.csv文件中。

$ echo "age, workclass, fnlwgt, education, education-num, marital-status, occupation, relationship, race, sex, capital-gain, capital-loss, native-country, class" > header.csv

在此示例中, 你使用了shell重定向>字符将cat的输出转储到adult.csv文件中。 >将创建文件或完全替换其内容(如果文件已存在)。加倍符号>>会将新内容附加到现有文件中, 而不会擦除其内容。

现在让我们将header.csv文件添加到adult.data文件的开头。同时, 将adult.data重命名为adult.csv, 因为它毕竟是CSV格式的文件。

$ cat header.csv adult.data > adult.csv

检查Adult.csv的第一行是否包含具有以下内容的列名:

$ head -n 1 adult.csv
age, workclass, fnlwgt, education, education-num, marital-status, occupation, relationship, race, sex, capital-gain, capital-loss, native-country, class
39, State-gov, 77516, Bachelors, 13, Never-married, Adm-clerical, Not-in-family, White, Male, 2174, 0, 40, United-States, <=50K

用sed修改文件

当文件损坏或格式错误(例如, 非UTF-8字符或逗号不正确)时, 会发生另一种频繁的数据挖掘情况。你可以纠正该文件, 而无需使用sed命令实际打开它。

通用sed模式是

$ sed "s/<string to replace>/<string to replace it with>/g" <source_file> > <target_file>.

adult.csv数据集使用?表示缺失值的字符。你可以使用sed将其替换为更适合的默认值。最好使用空字符串来表示缺少的值, 因为在将数据加载到Pandas DataFrame中时, 它将被解释为NaN值。

$ grep ", ?, " adult.csv | wc -l
2399

这样一来, 你可以算出2399行, 其中至少一列的缺失值用?表示。以下命令将所有列替换为?用一个空字符串。所有仅包含?, 后跟一个空格的单元格现在将真正为空。

$ sed "s/, ?, /, , /g" adult.csv >  adult.csv

请注意, 在源字符串和目标字符串中使用列定界符, 以避免替换可能出现在数据集中其他地方的合法问号。

子集大文件

现在想象一下, 你要处理的文件超过3000万行。在制作Python或R脚本时, 你将只想在原始大文件的样本上测试工作流, 而不必将整个数据集加载到内存中。你可以组合使用头和尾来创建原始数据集的子样本。

  • head输出文件的第一部分;
  • 尾巴输出文件的最后一部分

如你之前所见, 这些命令带有-n标志, 代表–lines, 它限制了输出中的行数。尾部还带有-f标志, 其中f代表–follow, 当将行添加到文件末尾时, 它将输出附加数据。当脚本使用tail -f <logfile>运行时, 这对于监视日志文件特别方便。

混合在管道符号中|使用头和尾, 你可以从源文件中提取一定数量的行, 并将内容导出到子文件。例如, 要提取从第100行开始的20行:

$ head -n 120 adult.csv | tail -n 20 > adult_sample.csv

请注意, 你首先将first_line + number_of_lines放在头, 然后在number_of_lines尾部放置。通用子设置命令为:

$ head -n <total_lines> <source_file> | tail -n <number_of_lines> > <target_file>

其中total_lines = first_line + number_of_lines。但是, 新的采样文件不再包含标题行。我们已经知道如何使用cat将标头重新添加到子文件中, 以连接子文件和之前创建的header.csv文件:

$ cat adult_sample.csv header.csv > adult_sample_with_header.csv

请注意, 你没有使用源文件名” adult \ _sample.csv”作为目标文件名, 而是创建了一个名为” adult \ _sample \ _with \ _header.csv”的新文件。使用cat时与源之一和目标名称相同, 将导致意外的文件内容。最好创建一个新文件作为cat命令的输出。

使用uniq查找重复项

使用uniq命令, 你可以在文件中找到相邻的重复行。 uniq带有几个标志, 更有用的是:

  • uniq -c:将重复计数添加到每一行;
  • uniq -d:仅输出重复的行;和
  • uniq -u:仅输出唯一的行。

但是, uniq不是明智的命令。如果重复的行不相邻, 则不会被检测到。这意味着你首先需要对文件进行排序。此命令将统计adult.csv中重复的行数。

$ sort adult.csv | uniq -d | wc -l
23

并显示有23个重复项。下一条命令获取具有重复计数的所有行的输出, 以反向排序并输出前3个重复项:

$ sort adult.csv | uniq -c | sort -r | head -n 3
3 25, Private, 195994, 1st-4th, 2, Never-married, ...
2 90, Private, 52386, Some-college, 10, Never-married, ...
2 49, Self-emp-not-inc, 43479, Some-college, 10, Married-civ-spouse, ...

通过将sort和uniq与不同的标志结合使用, 可以获得许多强大的选项。使用man sort和man uniq进一步探索这些命令。

选择带有剪切的列

CSV文件和Shell命令的妙处在于, 你还可以通过使用cut选择特定列来在列级别进行工作。 cut具有两个主要标志:-d指定列定界符, 和-f指定要处理的列。在下面的示例中, 你将使用cut来查找分类变量workclass(第2列)采用的唯一值的数量。

首先选择列工作类并直达标题以确认你具有正确的列:

$ cut -d ", " -f 2 adult.csv | head -3
workclass
State-gov
Self-emp-not-inc

现在, 要计算唯一性, 你可以对cut的输出进行排序并将结果通过管道传递给uniq -c, 如下所示:

$  cut -d ", " -f 2 adult.csv | sort | uniq -c
1837
 960  Federal-gov
2093  Local-gov
   7  Never-worked
22696  Private
1116  Self-emp-inc
2541  Self-emp-not-inc
1298  State-gov
  14  Without-pay
   1 workclass

例如, 这告诉你你有1837个空值, 并且主类到目前为止是具有22969次出现的Private类。

上面的命令行类似于应用于包含Adult.csv数据的DataFrame的value_counts()方法。

循环播放

到目前为止, 你基本上只处理一个文件。要重命名, 处理或传输大量文件, 应将循环添加到我们的Shell工具箱中。 bash shell中循环的通用格式为:

while true; do
    _do something_ ;
done

让我们开始吧。假设你有1000个文件名, 文件名中带有空格, 而你想用一个非下划线的” _”替换每个空格。

replace_source=' '
replace_target='_'
for filename in ./*.csv; do
    new_filename=${filename//$replace_source/$replace_target}
    mv "$filename" "$new_filename"
done

在这个例子中

  • 首先, 声明两个变量:replace_source和replace_target作为空格和下划线字符的占位符
  • 你遍历当前文件夹中的所有* .csv文件
  • 对于每个文件名, 你可以通过用下划线替换每个空格来创建一个new_filename
  • 然后使用mv命令将文件从当前文件名重命名为新文件名

实际上, 不仅使用shell循环浏览目录中的文件, 还创建了变量。

变量

你将以变量结尾此shell命令介绍。在shell中创建变量只需通过

$ varname='<a string>'
$ varname=a number

例如:

$ varname='Hello world'
$ varname=123.4

请注意, ” =”符号周围没有空格。 var ='<a string>’将不起作用。要返回变量值, 只需回显它:

$ echo $varname
123.4

要在脚本中使用它, 请将其封装在引号中, 如前所述:

$ mv "$filename" "$new_filename"

编写循环和使用变量为更复杂的文件操作打开了方便之门, 并且是shell脚本的门户, 这超出了本文的介绍。但是, 如果你从小处着手, 并随着信心的提高而提高, 那么shell脚本就足够简单了。

总结

Shell命令行作为数据科学家在你的日常工作中非常有用。还有更多示例和用例可以探索。正如你将看到的, 使用各种各样的可用shell命令和相关标志通常总是有不同的方法来达到特定的结果。在这种情况下, 保持简单永远是制胜法宝。

希望这里提供的示例将帮助你将Shell命令集成到数据处理工具包中。随时与我联系并在Twitter上分享你的Shell技巧:@alexip。

赞(0)
未经允许不得转载:srcmini » 8个有用的Shell数据科学命令

评论 抢沙发

评论前必须登录!