本文概述
- 快速笔记
- 用wc计数
- 用cat连接文件
- 用sed修改文件
- 子集大文件
- 使用uniq查找重复项
- 选择带有剪切的列
- 循环播放
- 变量
- 总结
你不可避免地会在冻结屏幕, 重新启动和长时间等待上花费大量时间。
但是, 大多数这些任务可以用几行代码来完成。而且, 熟悉一些简单的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
【8个有用的Shell数据科学命令】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输出文件的第一部分;
- 尾巴输出文件的最后一部分
混合在管道符号中|使用头和尾, 你可以从源文件中提取一定数量的行, 并将内容导出到子文件。例如, 要提取从第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:仅输出唯一的行。
$ 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
960Federal-gov
2093Local-gov
7Never-worked
22696Private
1116Self-emp-inc
2541Self-emp-not-inc
1298State-gov
14Without-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中创建变量只需通过
$ 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。
推荐阅读
- 什么是最好的统计编程语言(信息图)
- Scikit-Learn教程(棒球分析(2))
- NLP的歌词分析和R的机器学习
- 使用R和PhantomJS进行Web爬取
- Scikit-Learn教程(Python与机器学习)
- Scikit-Learn教程(棒球分析(1))
- 使用Scikit-Learn检测虚假新闻
- R教程中的算法交易
- 安卓手机开启通过wifi使用adb