資料的截取與邏輯判斷 - Linux

By Eartha
at 2018-06-29T11:31
at 2018-06-29T11:31
Table of Contents
※ 引述《egoweaver (Hiko)》之銘言:
: 啊,打完發現我不是在隔壁版。補個 Linux 點。用 awk 的話其實也滿快的:
: # 計算 A_1 與 A_2 相同的列數 (若它們分別為第一第二欄)
: awk '$1 == $2 {i++}END{print i}' [your raw data]
: # 計算 A_1 與 A_2 都同樣是 ./. 的列數
: awk '$1 == "./." && $2 == "./." {i++}END{print i}' [your raw data]
: # 計算 A_1 與 A_2 不相同的列數
: awk '$1 != $2 {i++}END{print i}' [your raw data]
: # 計算每列中有幾個 "./."
: awk '{for(i = 1; i <= NF; i++) {if($i == "./.") n++}; \
: print n >> "number.txt";}' [your raw data]
: # 如果要把 "./." 的個數當作一欄併回原檔案
: paste [your raw data] number.txt >> newfile.txt
: ※ 引述《k97231 (AL)》之銘言:
: : 基本上的資料格式長這樣
: : ID A_1 A_2 B_1 B_2 ……
: : 1 0/0 0/0
: : ……
: : 依據相同字母的樣本(像是A_1和A_2)
: : 逐列統計四種欄位的數量
: : 1. A_1和A_2相同
: : 2. A_1和A_2都一樣是./.
: : 3. A_1和A_2不一樣
: : 4. 以及任一樣本含有./.的欄位數量
這類型的統計用 awk 還真的滿簡單的.
不過麻煩的是在這一句 「依據相同字母的樣本(像是A_1和A_2)」
也就是 A_1 跟 A_2 統計, B_1 跟 B_2 統計, 是吧?
如果需要統計的欄位很多 (ex: A_1...Z_1), 那就比較煩一點..
考慮單一個資料來說.
無腦的把條件直接寫下來
SCREEN:working rickie$ cat stats.awk
BEGIN{
cnt_match=0;
cnt_dot_match=0;
cnt_dot=0;
cnt_not_match=0;
}
(NR > 1){
if ( $2 == $3 ) {cnt_match++;}
if ( $2 == $3 && $2 == "./." ) {cnt_dot_match++;}
if ( $2 == "./." || $3 == "./." ){cnt_dot++;}
if ( $2 != $3 ) {cnt_not_match++;}
}
END{
printf(" A_1 = A_2 : %d\n",cnt_match);
printf(" A_1 = A_2 = ./. : %d\n",cnt_dot_match);
printf("A_1 or A_2 = ./. : %d\n",cnt_dot);
printf(" A_1 != A_2 : %d\n",cnt_not_match);
}
從你的 raw data 複製了一份 600 萬筆資料的檔案
SCREEN:working rickie$ wc -l temp2.dat
6000001 temp2.dat
試跑一下
SCREEN:working rickie$ time awk -f stats.awk temp2.dat
A_1 = A_2 : 3000000
A_1 = A_2 = ./. : 1000000
A_1 or A_2 = ./. : 2000000
A_1 != A_2 : 3000000
real 0m10.119s
user 0m9.940s
sys 0m0.065s
稍微優化一下
SCREEN:working rickie$ cat stats2.awk
BEGIN{
cnt_match=0;
cnt_dot_match=0;
cnt_dot=0;
cnt_not_match=0;
}
(NR > 1){
if ( $2 == $3 ) {
cnt_match++;
if ($2 == "./." ) {
cnt_dot_match++;
cnt_dot++;
}
} else {
cnt_not_match++;
if ( $2 == "./." || $3 == "./." ){cnt_dot++;}
}
}
END{
printf(" A_1 = A_2 : %d\n",cnt_match);
printf(" A_1 = A_2 = ./. : %d\n",cnt_dot_match);
printf("A_1 or A_2 = ./. : %d\n",cnt_dot);
printf(" A_1 != A_2 : %d\n",cnt_not_match);
}
再跑一次
SCREEN:working rickie$ time awk -f stats2.awk temp2.dat
A_1 = A_2 : 3000000
A_1 = A_2 = ./. : 1000000
A_1 or A_2 = ./. : 2000000
A_1 != A_2 : 3000000
real 0m4.999s
user 0m4.937s
sys 0m0.044s
如果可以不要檔頭, 那 (NR > 1) 這個判斷拿掉, 可以再少一點點時間
SCREEN:working rickie$ time awk -f stats3.awk temp3.dat
A_1 = A_2 : 3000000
A_1 = A_2 = ./. : 1000000
A_1 or A_2 = ./. : 2000000
A_1 != A_2 : 3000000
real 0m4.805s
user 0m4.749s
sys 0m0.039s
大概是醬~
還有 awk 變數其實不用預先宣告, BEGIN 裡其實可以省略
單純只是個人強迫症發作...
--
文章代碼(AID): #1H6m-prS (Gossiping) [ptt.cc] [問卦] 有沒有雪藏的八卦?
--
: 啊,打完發現我不是在隔壁版。補個 Linux 點。用 awk 的話其實也滿快的:
: # 計算 A_1 與 A_2 相同的列數 (若它們分別為第一第二欄)
: awk '$1 == $2 {i++}END{print i}' [your raw data]
: # 計算 A_1 與 A_2 都同樣是 ./. 的列數
: awk '$1 == "./." && $2 == "./." {i++}END{print i}' [your raw data]
: # 計算 A_1 與 A_2 不相同的列數
: awk '$1 != $2 {i++}END{print i}' [your raw data]
: # 計算每列中有幾個 "./."
: awk '{for(i = 1; i <= NF; i++) {if($i == "./.") n++}; \
: print n >> "number.txt";}' [your raw data]
: # 如果要把 "./." 的個數當作一欄併回原檔案
: paste [your raw data] number.txt >> newfile.txt
: ※ 引述《k97231 (AL)》之銘言:
: : 基本上的資料格式長這樣
: : ID A_1 A_2 B_1 B_2 ……
: : 1 0/0 0/0
: : ……
: : 依據相同字母的樣本(像是A_1和A_2)
: : 逐列統計四種欄位的數量
: : 1. A_1和A_2相同
: : 2. A_1和A_2都一樣是./.
: : 3. A_1和A_2不一樣
: : 4. 以及任一樣本含有./.的欄位數量
這類型的統計用 awk 還真的滿簡單的.
不過麻煩的是在這一句 「依據相同字母的樣本(像是A_1和A_2)」
也就是 A_1 跟 A_2 統計, B_1 跟 B_2 統計, 是吧?
如果需要統計的欄位很多 (ex: A_1...Z_1), 那就比較煩一點..
考慮單一個資料來說.
無腦的把條件直接寫下來
SCREEN:working rickie$ cat stats.awk
BEGIN{
cnt_match=0;
cnt_dot_match=0;
cnt_dot=0;
cnt_not_match=0;
}
(NR > 1){
if ( $2 == $3 ) {cnt_match++;}
if ( $2 == $3 && $2 == "./." ) {cnt_dot_match++;}
if ( $2 == "./." || $3 == "./." ){cnt_dot++;}
if ( $2 != $3 ) {cnt_not_match++;}
}
END{
printf(" A_1 = A_2 : %d\n",cnt_match);
printf(" A_1 = A_2 = ./. : %d\n",cnt_dot_match);
printf("A_1 or A_2 = ./. : %d\n",cnt_dot);
printf(" A_1 != A_2 : %d\n",cnt_not_match);
}
從你的 raw data 複製了一份 600 萬筆資料的檔案
SCREEN:working rickie$ wc -l temp2.dat
6000001 temp2.dat
試跑一下
SCREEN:working rickie$ time awk -f stats.awk temp2.dat
A_1 = A_2 : 3000000
A_1 = A_2 = ./. : 1000000
A_1 or A_2 = ./. : 2000000
A_1 != A_2 : 3000000
real 0m10.119s
user 0m9.940s
sys 0m0.065s
稍微優化一下
SCREEN:working rickie$ cat stats2.awk
BEGIN{
cnt_match=0;
cnt_dot_match=0;
cnt_dot=0;
cnt_not_match=0;
}
(NR > 1){
if ( $2 == $3 ) {
cnt_match++;
if ($2 == "./." ) {
cnt_dot_match++;
cnt_dot++;
}
} else {
cnt_not_match++;
if ( $2 == "./." || $3 == "./." ){cnt_dot++;}
}
}
END{
printf(" A_1 = A_2 : %d\n",cnt_match);
printf(" A_1 = A_2 = ./. : %d\n",cnt_dot_match);
printf("A_1 or A_2 = ./. : %d\n",cnt_dot);
printf(" A_1 != A_2 : %d\n",cnt_not_match);
}
再跑一次
SCREEN:working rickie$ time awk -f stats2.awk temp2.dat
A_1 = A_2 : 3000000
A_1 = A_2 = ./. : 1000000
A_1 or A_2 = ./. : 2000000
A_1 != A_2 : 3000000
real 0m4.999s
user 0m4.937s
sys 0m0.044s
如果可以不要檔頭, 那 (NR > 1) 這個判斷拿掉, 可以再少一點點時間
SCREEN:working rickie$ time awk -f stats3.awk temp3.dat
A_1 = A_2 : 3000000
A_1 = A_2 = ./. : 1000000
A_1 or A_2 = ./. : 2000000
A_1 != A_2 : 3000000
real 0m4.805s
user 0m4.749s
sys 0m0.039s
大概是醬~
還有 awk 變數其實不用預先宣告, BEGIN 裡其實可以省略
單純只是個人強迫症發作...
--
文章代碼(AID): #1H6m-prS (Gossiping) [ptt.cc] [問卦] 有沒有雪藏的八卦?
→ liusim:我覺得應該還是念雪藏 你們不覺得念雪藏怪怪的嗎?02/13 12:03
→ ispy03532003:原來如此 要唸"藏"阿 之前都一直講"藏"02/13 12:04
→ koster:我真的不知道要念雪藏 一直都以為念雪藏是對的 長知識了02/13 12:06
推 pkmu8426:其實藏和藏都是錯的 只有藏才是對的02/13 12:11
噓 Eternity424:幹你娘 你們都打藏誰知道講哪個音02/13 12:16
--
Tags:
Linux
All Comments

By Jacob
at 2018-06-30T05:47
at 2018-06-30T05:47

By Daniel
at 2018-07-03T15:44
at 2018-07-03T15:44

By Rosalind
at 2018-07-06T17:34
at 2018-07-06T17:34

By Enid
at 2018-07-11T10:15
at 2018-07-11T10:15

By Zanna
at 2018-07-14T18:54
at 2018-07-14T18:54

By Daph Bay
at 2018-07-19T10:48
at 2018-07-19T10:48
Related Posts
資料的截取與邏輯判斷

By Andrew
at 2018-06-28T18:23
at 2018-06-28T18:23
資料的截取與邏輯判斷

By Doris
at 2018-06-26T21:26
at 2018-06-26T21:26
Ubuntu 16 拔掉hdmi無法開機

By Susan
at 2018-06-25T13:01
at 2018-06-25T13:01
ubuntu 打不開

By Jacob
at 2018-06-21T22:51
at 2018-06-21T22:51
尋找空的資料夾或是非空的資料夾?

By Ina
at 2018-06-21T10:11
at 2018-06-21T10:11