Menghitung nilai rasio dalam suatu garis yang berisi bilangan biner 0 & 1

Saya memiliki file data yang berisi lebih dari 2000 baris dan 45001 kolom.

Kolom pertama sebenarnya adalah "string" yang menjelaskan tipe datanya.

Mulai dari kolom #2, sampai dengan kolom #45001, datanya direpresentasikan sebagai

"1"

or

"0"

Misalnya pola data dalam satu garis adalah

(0 0 0 1 1 0 1 1 1 0 1 1 1 1 0 0 0 1 0 0 1 1 1 0 0)

Jumlah datanya adalah 25. Dalam baris data ini terdapat 5 subkelompok yang dibuat hanya dengan angka "1", misal. (11 111 1111 1 111 ). Angka "0" di antara subgrup diasumsikan sebagai "pembatas". Jumlah semua "1" adalah = 13.

Saya ingin menghitung rasio

(total semua "1" / total jumlah subgrup yang dibuat hanya dengan "1")

Itu adalah

(13/5).

Saya mencoba dengan kode ini untuk menghitung total semua "1" ;

awk -F '0' '{print NF}' < inputfile.in

Ini memberi nilai 13.

Tapi saya tidak tahu bagaimana melangkah lebih jauh dari sini untuk menghitung rasio yang saya inginkan. Saya tidak tahu bagaimana menemukan jumlah subgrup dalam setiap baris karena jumlah kemunculan "1" dan "0" adalah acak.

Ingin mendapatkan bantuan untuk menyelesaikan masalah ini.

Hargai bantuan apa pun sebelumnya.


person Vijay    schedule 15.03.2015    source sumber
comment
posting masukan yang tepat. apakah ada spasi sebelum dan sesudah angka ti?   -  person Avinash Raj    schedule 15.03.2015
comment
Ini adalah contoh data [BMR_10@O24-BMR_6@O13-H13 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1]. Kolom pertama adalah string dan sisanya adalah data dari satu baris saja. Saya tidak dapat menampilkan file sebenarnya karena ukurannya sekitar 5MB.   -  person Vijay    schedule 15.03.2015


Jawaban (2)


Tidak jelas bagi saya dari uraiannya apa format file inputnya. Asumsikan inputnya terlihat seperti:

$ cat file
0 0 0 1 1 0 1 1 1 0 1 1 1 1 0 0 0 1 0 0 1 1 1 0 0

Untuk menghitung jumlah satuan dan banyaknya kelompok satuan serta mengambil perbandingannya:

$ awk '{f=0;s1=0;s2=0;for (i=2;i<=NF;i++){s1+=$i;if ($i && !f)s2++;f=$i}; print s1/s2}' file
2.6

Pembaruan: Menangani semua angka nol

Misalkan salah satu baris dalam file memiliki semua angka nol:

$ cat file
0 0 0 1 1 0 1 1 1 0 1 1 1 1 0 0 0 1 0 0 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Untuk baris kedua, kedua jumlahnya adalah nol yang akan menyebabkan kesalahan pembagian dengan nol. Kita dapat menghindarinya dengan menambahkan pernyataan if yang akan mencetak rasio jika ada atau 0/0 jika tidak:

if (s2>0)print s1/s2; else print s1"/"s2

Kode lengkapnya sekarang:

$ awk '{f=0;s1=0;s2=0;for (i=2;i<=NF;i++){s1+=$i;if ($i && !f)s2++;f=$i}; if (s2>0)print s1/s2; else print s1"/"s2}' file
2.6
0/0

Bagaimana itu bekerja

Kode ini menggunakan tiga variabel. f adalah tanda yang bernilai benar (1) jika kita saat ini berada dalam kelompok satu dan bernilai salah (0) jika tidak. s1 adalah jumlah yang ada di telepon. s2 adalah jumlah kelompok yang ada di garis.

  • f=0;s1=0;s2=0

    Di awal setiap baris, kami menginisialisasi variabel.

  • for (i=2;i<=NF;i++){s1+=$i;if ($i && !f)s2++;f=$i}

    Kita mengulang setiap field pada baris yang dimulai dengan field 2. Jika field tersebut berisi 1, kita menambah penghitung s1. Jika bidangnya adalah 1 dan merupakan awal dari grup baru, kita menambah s2.

  • if (s2>0)print s1/s2; else print s1"/"s2}

    Jika kami menemukan setidaknya satu, kami mencetak rasio s1/s2. Jika tidak, kami mencetak 0/0.

person John1024    schedule 15.03.2015
comment
Tapi pak, ada baris yang datanya berisi baris yang semuanya nol, seperti (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0). Jadi ketika saya mencoba, saya mendapat pesan kesalahan ([vijay@glycogpu process-rawData]$ ./find-sum-and-ratio.sh 947 17 55.7059 awk: (FILENAME=outPut3.dat FNR=2) fatal: pembagian dengan nol dicoba). Mungkinkah hal ini dapat diatasi? - person Vijay; 15.03.2015
comment
@Vijay oke. Jawaban yang diperbarui memiliki kode untuk mengatasinya. - person John1024; 15.03.2015
comment
Ini tidak memberikan data yang benar jika Anda menambahkan kolom nomor 1 dengan informasi data. op: Start from column #2, up to column #45001, the data is reprsented as 0 or 1 - person Jotne; 15.03.2015

person    schedule
comment
Ini tidak memberikan data yang benar jika kolom terakhir berisi 1. Coba, misalnya, echo data 0 1 1 | awk -F1 '{gsub(/ +/,"");n=split($0,a,"[^1]+")-2;print (n?(NF-1)/n:"0")}'. Hasilnya harus 2, Kode mengembalikan 0. - person John1024; 15.03.2015
comment
@ John1024 Ini juga akan gagal pada kolom 1 kolom info berisi 1 seperti pada komentar OP. Akan mencoba memperbaikinya. - person Jotne; 15.03.2015
comment
Diperbarui dengan contoh data baru untuk menghitung dengan benar. - person Jotne; 15.03.2015