當前位置:
首頁 > 知識 > 數據科學家的命令行技巧

數據科學家的命令行技巧


來自:開源中國社區


鏈接:https://www.oschina.net/translate/cli-4-ds


原文:http://kadekillary.work/post/cli-4-ds/







對於許多數據科學家來說,數據操作起始於Pandas或Tidyverse。從理論上看,這個概念沒有錯。畢竟,這是為什麼這些工具首先存在的原因。然而,對於分隔符轉換等簡單任務來說,這些選項通常可能是過於重量級了。

有意掌握命令行應該在每個開發人員的技能鏈上,特別是數據科學家。學習shell中的來龍去脈無可否認地會讓你更高效。

除此之外,命令行還在計算方面有一次偉大的歷史記錄。例如,awk - 一種數據驅動的腳本語言。Awk首次出現於1977年,它是在傳奇的K&R一書中的K,Brian Kernighan的幫助下出現的。在今天,大約50年之後,awk仍然與每年出現的新書保持相關聯! 因此,可以肯定的是,對命令行技術的投入不會很快貶值的。



我們會談及的內容






  • ICONV



  • HEAD



  • TR



  • WC



  • SPLIT



  • SORT & UNIQ



  • CUT



  • PASTE



  • JOIN



  • GREP



  • SED



  • AWK




ICONV




文件編碼總是棘手的問題。目前大部分文件都是採用的 UTF-8 編碼。要想了解 UTF-8 的魔力,可以看看這個優秀的視頻。儘管如此,有時候我們還是會收到非 UTF-8 編碼的文件。這種情況下就需要嘗試轉碼。iconv 就是這種狀況下的救世主。


iconv 是一個簡單的程序,可以輸入某種編碼的文本,然後以另一種編碼輸出。



# Converting -f (from) latin1 (ISO-8859-1)


# -t (to) standard UTF_8

iconv

 -f ISO-

8859

-

1

 -t UTF-

8

 < input.txt > output.txt





  • 有用的選項:




    • head -n 輸出指定行



    • head -c 輸出指定的位元組




HEAD




如果你是重度Pandas的用戶,那麼你會對head很熟悉。通常在處理新數據時,我們想要做的第一件事就是了解究竟存在那些東西。這會引起Panda啟動,讀取數據,然後調用df.head() - 很費勁,至少可以說。head,不需要任何標誌,將輸出文件的前10行。head真正的能力在於徹查清除操作。 例如,如果我們想將文件的分隔符從逗號改變為pipe通配符。一個快速測試將是:head mydata.csv | sed "s/,/|/g"



# Prints out first 10 lines


head

 filename.csv

# Print first 3 lines


head -n 

3

 filename.csv





  • 有用的選項:




    • head -n 輸出指定行



    • head -c 輸出指定的位元組




TR命令




Tr類似於翻譯,它是基於文件清理的一個強大使用的工具。一個理想的用法是替換文件中的分隔符。



#將文件中的製表符分割轉換成逗號


cat

 tab_delimited.txt | tr 

""

 

","

 comma_delimited.csv



Tr的另一個特性是在你的處理中設置上所有的[:class:]變數。包括:



[

:alnum:

] 所有字母和數字
[

:alpha:

] 所有字母
[

:blank:

] 所有水平空白
[

:cntrl:

] 所有控制字元
[

:digit:

] 所有數字
[

:graph:

] 所有可列印的字元,不包括空格
[

:lower:

] 全部小寫字母
[

:print:

] 所有可列印的字元,包括空格
[

:punct:

] 所有標點符號
[

:space:

] 所有的水平或垂直空格
[

:upper:

] 全部大寫字母
[

:xdigit:

] 所有十六進位數字



可以將這些多樣化的變數鏈接在一起,組成一個強大的程序。下面是一個基於字數統計的程序,用來檢查你的README文件是否使用過度。



cat README.md | tr "[

:punct:

][

:space:

]



另外一個例子用於正則表達式



# 將所有的大寫字母轉換成小寫


cat

 filename.csv | tr 

"[A-Z]"

 

"[a-z]"






  • 有用的選項:




    • tr -d刪除字元



    • tr -s壓縮字元



    • 退格



    • 換頁



    • 垂直選項卡



    • NNN八進位值為NNN的字元




WC




字數統計。它的價值主要體現在使用 -l 參數可以進行行數統計。



# Will return number of lines in CSV


wc

 -l gigantic_comma.csv



個用這個工具來驗證各個命令的輸出實在方便。因此,如果我們要在文件中轉換分隔符,然後運行 wc -l,驗證總行數是相同的。如果不同,我們就知道一定是哪裡出錯了。






  • 常用選項:




    • wc -c 列印位元組數



    • wc -m 列印字元數



    • wc -L 列印最長一行的長度



    • wc -w 列印字數




SPLIT命令




文件大小可以有顯著變化。根據工作的不同,拆分文件是有益的,就像split。基本用法如下:



#我們拆分這個CSV文件,每500行分割為一個新的文件new_filename

split

 -l 

500

 filename.csv new_filename_

# filename.csv


# ls output


# new_filename_aaa


# new_filename_aab


# new_filename_aac




兩個地方很奇怪:一個是命名方式,一個是缺少擴展名。後綴約定可以通過-d標識來數字化。添加文件擴展名,你需要執行下面這個find命令。他會給當前文件夾下的所有文件追加.csv後綴,所以需要小心使用。



find . -

type

 f -

exec

 mv 

"{}"

 

"{}"

.csv ;

# ls output


# filename.csv.csv


# new_filename_aaa.csv


# new_filename_aab.csv


# new_filename_aac.csv







  • 有效的選項:




    • split -b按特定位元組大小拆分



    • split -a生成長度為N的後綴



    • split -x使用十六進位後綴分割




SORT & UNIQ




前面的命令是顯而易見的:他們按照自己說的做。這兩者提供了最重要的一擊(即去重單詞計數)。這是由於有uniq,它只處理重複的相鄰行。因此在管道輸出之前進行排序。一個有趣的事情是,sort -u將獲得與sort file.txt | uniq相同的結果。




Sort確實對數據科學家來說是一種很有用的小技巧:能夠根據特定的列對整個CSV進行排序。



# Sorting a CSV file by the second column alphabetically


sort

 -t

","

 -k2,

2

 filename.csv

# Numerically


sort

 -t

","

 -k2n,

2

 filename.csv

# Reverse order


sort

 -t

","

 -k2nr,

2

 filename.csv



這裡的-t選項是指定逗號作為分隔符。通常假設是空格或製表符。此外,-k標誌是用來指定我們的鍵的。它的語法是-km,n,m是起始欄位,n是最後一個欄位。






  • 有用的選項:




    • sort -f 忽略大小寫



    • sort -r 逆序



    • sort -R 亂序



    • uniq -c 計算出現次數



    • uniq -d 只列印重複行




CUT命令




cut用於刪除列。舉個栗子,如果我們只想要第一列和第三列。



cut

 

-d

-f

 1,3 

filename

.csv




選擇除了第一列以外的所有列



cut

 

-d

-f

 2

-

 

filename

.csv




與其他的命令組合使用,cut命令作為過濾器



#列印存在「some_string_value」的第

1

列和第

3

列的前

10

head filename.csv | 

grep

 

"some_string_value"

 | cut -d, -f 

1

,

3




找出第二列中唯一值的數量。



cat filename.csv | cut -d, -f 

2

 | 

sort

 | uni

q | wc -l
# 計算唯一值出現的次數,限制輸出前10個結果
cat filename.csv |

 cut -d, -f 

2

 | 

sort

 | uniq -c | head



PASTE




paste 是個有趣的小命令。如果你想合併兩個文件,而這兩個文件的內容又正好是有序的,那 paste 就可以這樣做。



# names.txt


adam


john
zach

# jobs.txt


lawyer
youtuber
developer


# Join the two into a CSV

paste

 -d 

","

 names.txt jobs.txt > person_data.txt


# Output


adam

,lawyer

john

,youtuber

zach

,developer



關於更多 SQL_-esque 變體,請看下面。




JOIN




Join是一種簡單的、准切向的SQL。最大的區別在於Join將返回所有列,匹配可能只發生在一個欄位上。默認情況下,join將嘗試使用第一列作為匹配鍵。對於不同的結果,需要以下語法:



# Join the first file (-1) by the second column


# and the second file (-2) by the first

join

 -t

","

 -

1

 

2

 -

2

 

1

 first_file.txt second_file.txt



標準連接是一個內部連接。然而,外部連接也可以通過-af滯後來實現。另一個值得注意的是-e標誌,如果發現有欄位丟失,它可以用來替換成其他值。



# Outer 

join

replace

 blanks 

with

 

NULL

 

in

 columns 

1

 

and

 

2


# -o which fields 

to

 substitute - 

0

 

is

 key, 

1.1

 

is

 first column, etc...

join

 -t

","

 

-1

 

2

 -a 

1

 -a2 -e 

" NULL" -o "0,1.1,2.2" first_file.txt second_file.txt




雖然它不是最容易使用的命令,但是在絕望的時刻,它就是唯一可用的措施。






  • 常用的選項:




    • join -a 列印未成對的行



    • join -e 替換缺失欄位



    • join -j 等同於 -1 FIELD -2 FIELD




GREP




全局搜索正則表達式並輸出,或使用grep;可能是最知名的命令,並且有很好的理由。 Grep具有很強的能力,特別是在大型代碼庫中查找方法。在數據科學領域,它充當了其他命令的改進機制。但其標準用法也很有用。



# 遞歸搜索並列出當前目錄下包含"word"的所有文件


grep

 -lr 

"word"

 .

# 列出包含word的文件數目


grep

 -lr 

"word"

 . | wc -l



對包含word/pattern的行數進行計數



grep

 -c 

"some_value"

 filename.csv

# 同樣的功能,但是按照文件名列出當前目錄下所有包含該關鍵詞的文件

grep

 -c 

"some_value"

 *



Grep使用or運算符- |來檢索多個值.



grep

 

"first_value|second_value"

 filename.csv





  • 有用的選項




    • alias grep="grep --color=auto" 使grep支持彩色輸出



    • grep -E 使用擴展正則表達式



    • grep -w 僅匹配完整單詞



    • grep -l 列印匹配文件的名稱



    • grep -v 倒序匹配




大殺器




Sed和Awk是本文兩個最有用的命令。為了簡潔,我不會討論那些令人費解的細節。相反,我會討論各種各樣的命令來證明他們令人印象深刻的實力。如果你想了解的更多,這本書就可以。




SED




在內核中sed是一個流編輯器。它擅長替換,但是也可以用來重構。



最基本的sed命令包含了s/old/new/g。也就是全局搜索舊值,替換新值。沒有/g 我們的命令可能在第一次出現舊值就會終止。



為了儘快了解它的能力,我們來看一個例子。在這個情況你會拿到下面的文件:



balance,name

$1

,000,john

$2

,000,jack



我們要做的第一件事就是移除美元符。-i 標識表示就地修改。""就是代表一個零長度文件擴展,因此重寫我們的初始文件。理想情況下,你會單獨測試這些並輸出到一個新文件。



sed

 -i 

""

 

"s/$//g"

 data.txt

# balance,name


# 1,000,john


# 2,000,jack




下一步,我們的balance列的逗號。



sed

 -i 

""

 

"s/([0-9]),([0-9])//g"

 data.txt

# balance,name


# 1000,john


# 2000,jack




最終,Jack有一天起來並準備辭職了。所以,再見吧,我的朋友。



sed

 -i 

""

 

"/jack/d"

 data.txt

# balance,name


# 1000,john




就像你所看到的,sed功能強大,但是樂趣不止於此。




AWK




最好的放最後。Awk不僅是一個簡單的命令:它是一個成熟的語言。在本文中包含的每一個命令中,awk目前是最酷的。如果你發現它令你印象深刻,這有大量的資源- 看這,這,和這。



awk包含的常用案例:







  • 文本處理



  • 格式化文本報告



  • 執行計算操作



  • 執行字元串操作




Awk在其最初雛形可以與grep平行。



awk

 

"/word/"

 filename.csv



或者多使用一點魔法,讓grep和cut結合。在這,awk對所有行通過word列印了以tab分隔的第三和第四列。-F,只是將分隔符變為逗號。



awk

 -F, 

"/word/ { print 

$3

 "" 

$4

 }"

 filename.csv



Awk具有大量有用的內置變數。例如, NF -欄位數 - 和NR - 記錄數。為了獲取文件中這53個記錄:



awk

 -F, 

"NR == 53"

 filename.csv



添加一個小竅門可以基於一個值或者多個值過濾。下面的第一個例子,會列印這些記錄中第一列為string的行數和列。



awk

 -F, 

$1

 == "string" { print NR, 

$0

 } "

 filename.csv

# Filter based off of numerical value in second column


awk -F, 

$2

 == 1000 { print NR, 

$0

 } "

 filename.csv



多數值表達式:



# Print line number and columns where column three greater


# than 2005 and column five less than one thousand

awk

 -F, 

$3

 >= 2005 && 

$5

 <= 1000 { print NR, 

$0

 } "

 filename.csv



計算第三列之和:



awk

 -F, 

"{ x+=

$3

 } END { print x }"

 filename.csv



計算那些第一列值為「something」的第三列之和。



awk

 -F, 

"

$1

 == "something" { x+=

$3

 } END { print x }"

 filename.csv



獲取文件的行數列數:



awk -F, "

END

 { print NF, NR }

" filename.csv

# Prettier version

awk -F, "

BEGIN

 { print 

"COLUMNS"

"ROWS"

 }; 

END

 { print NF, NR }

" filename.csv




列印出現過兩次的行:



awk

 -F, 

"++seen[

$0

] == 2"

 filename.csv



移除多行:



# Consecutive lines


awk

 

"a !~ 

$0

; {a=

$0

}"

]

# Nonconsecutive lines


awk 

"! a[

$0

]++"

 filename.csv

# More efficient


awk 

"!(

$0

 in a) {a[

$0

];print}




使用內置函數gsub()替換多個值。



awk

 

"{gsub(/scarlet|ruby|puce/, "red"); print}"




這個awk命令合併了多個CSV文件,忽略頭並在結尾追加。



awk

 

"FNR==1 && NR!=1{next;}{print}"

 

*.csv

 > final_file.csv



需要精簡一個大文件?好的,awk可以在sed的幫助下完成這件事。具體來說,基於一個行數,這個命令將一個大文件分為多個小文件。這個一行文件也會添加一個擴展名。



sed

 

"1d;

$d

"

 filename.csv | awk 

"NR%NUMBER_OF_LINES==1{x="filename-"++i".csv";}{print > x}"

# Example: splitting big_data.csv into data_(n).csv every 100,000 lines

sed 

"1d;

$d

"

 big_data.csv | awk 

"NR%100000==1{x="data_"++i".csv";}{print > x}"




結束前




命令行擁有無窮的力量。本文所涵蓋的命令行知識足以讓你從零基礎到入門。除了這些已涉及的內容外,針對日常數據操作還有需要可考慮的實用程序。Csvkit, xsv和q是其中三個值得關注的。如果你希望進一步深入到命令行的數據科學領域,那麼請看此書。它也可以在此免費獲得!




●編號562,輸入編號直達本文



●輸入m獲取文章

目錄

推薦↓↓↓



大數據與人工智慧


更多推薦

18個技術類公眾微信


涵蓋:程序人生、演算法與數據結構、黑客技術與網路安全、大數據技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Linux學習 的精彩文章:

詳細到沒朋友,一文幫你理清Linux 用戶與用戶組關係

TAG:Linux學習 |