İlk satıra göre sütunlar nasıl sıralanır?


12

Çok büyük bir veri kümesinin (1000 satır ve 700000 sütun) sütunlarını sıralamam gerekiyor. Örnek olarak, sütunlarım rastgele düzenlenmiştir: col1 col4 col3 col2 ve bunu sıralamam gerekiyor.

Bazı komutları deniyorum ama başarılı olamadım.

misal:

ID M2 M5 M8 M1 M3 M9 .....M7000000
Animal1 1 0 2 1 0 2 .....1
Animal2 0 1 2 0 1 1 .....0
Animal3 2 1 0 1 2 1 .....0
.
.
.
.
Animaln

Bu örnekte, noktalar çok fazla sütun ve satır var demektir. Yine, sütunlar gibi olması gerekir:

ID M1 M2 M3 M4 M5 M6 .....M7000000
Animal1 1 0 2 1 0 2 .....1
Animal2 0 1 2 0 1 1 .....0
Animal3 2 1 0 1 2 1 .....0
.
.
.
.
Animaln

teşekkür ederim


Veri kümesinin birkaç satırını içeren bir örnek ekleyebilir misiniz?
jcbermu

beklenen sonucunuz yalnızca ilk satırda sıralanıyor, diğer değerler aynı kalıyor, neden?
RomanPerekhrest

Aslında, sütunları takip etmesi gerekiyor, örneğin bir hataydı. üzgünüm
LLVerardo

İlk satıra göre tüm sütunun sıralanması gerekir.
LLVerardo

2
Geçiş yapın, ilk sütuna göre sıralayın, geri çevirin.
Satō Katsura

Yanıtlar:


10

GNU datamashve GNU ile sort:

datamash transpose -t ' ' -H <file_in.csv | sort -V | datamash transpose -t ' ' -H >file_out.csv

Bu, "makul derecede küçük" veriler için uygundur. Dosyanızla çalışabilir veya çalışmayabilir.

Düzenleme: Aşağıdaki dönüşümler olmadan çözümler daha az kaynak yoğun olmalıdır.


1
Rs komutu için daha hafif bir alternatif olabilir datamashmesela rs -T < file_in.csv | sort | rs -T -C' '( rsbir Debian tabanlı sistemlerde paket olarak mevcut olmalıdır)
steeldriver

2
FWIW, rs("bir veri dizisini yeniden şekillendir") bazı BSD'lerin temel sistemlerinde kullanılabilir.
Kusalananda

6
perl -pale '
   $. == 1 and
   @I = map  { $_->[1] }
        sort { $a->[0] <=> $b->[0] }
        map  { [ $F[$_] =~ /^M(\d+)$/, $_ ] } 1..$#F;
   $_ = "@F[0, @I]";
' yourlargefile

  1. İlk satır Miçin, başlangıçta meydana gelen rakamdan sonra sayısal kısımlarını kullanarak, iyi bilinenleri kullanarak 2. ... son sütunlarını sayısal olarak sıralarız Schwartzian maneuver. Bu bize sütunların sayısal olarak sıralanmış sırada (M1, M2, M3, ...) yeniden sıralanan indeksleri verir.
  2. Geriye kalan tek şey @I, @Föğeleri yeniden düzenlemek için gelen bu endeksleri kullanmaktır .
  3. Diziyi çift tırnaklı bir formda atamak, diziyi boşluklar ayrılmış bir dizeye dönüştürür.
  4. -pPerl seçeneği arasında kendyaz sağlayan $_içerikleri, -leklemek zorundadır newline.

6

Perl modülünü kullanma Sort :: Naturally

veri girişi

ID M2 M5 M8 M1 M3 M9 M700000
A1 m1,2 m1,5 m1,8 m1,1 m1,3 m1,9 m1,7000000
A2 m2,2 m2,5 m2,8 m2,1 m2,3 m2,9 m2,7000000
A3 m3,2 m3,5 m3,8 m3,1 m3,3 m3,9 m3,7000000
A1000 m1000,2 m1000,5 m1000,8 m1000,1 m1000,3 m1000,9 m1000,7000000
perl -MSort::Naturally -lane '
  if ($. == 1) {
    @indices = (0, map  { $_->[0] }
                   sort { ncmp($a->[1], $b->[1]) }
                   map  { [$_, $F[$_]] }
                   1..$#F
               );
    $, = " ";
  }
  print @F[@indices]
' test.data

çıktı

ID M1 M2 M3 M5 M8 M9 M700000
A1 m1,1 m1,2 m1,3 m1,5 m1,8 m1,9 m1,7000000
A2 m2,1 m2,2 m2,3 m2,5 m2,8 m2,9 m2,7000000
A3 m3,1 m3,2 m3,3 m3,5 m3,8 m3,9 m3,7000000
A1000 m1000,1 m1000,2 m1000,3 m1000,5 m1000,8 m1000,9 m1000,7000000

En zarif için +1, sütun adları için çok belirli bir önek kabul etmez, bir geçiş çözümü.
arielf

4

Eğer varsa rsyardımcı program yüklü, bunu yapabilirsiniz:

rs -c' ' -T | {
    stdbuf -i0 sed "1q"
    sort -V
} | rs -C' ' -T

Veya hepsi bir satırda:

rs -c' ' -T | { stdbuf -i0 sed "1q"; sort -V ; } | rs -C' ' -T
  • Birincisi rsgirdi verilerini aktarır (boşlukla ayrılmış alanlarla)
  • Komut grubu:
    • sedilk satırı okur, çıkar, sonra çıkar, borunun geri kalanını rsel değmeden bırakır . giriş arabelleğini kapatarak yalnızca ilk satırın sonuna kadar okunduğundan stdbufemin olmak gerekir.sed
    • sortkalan satırlar
  • İkincisi rs, elde edilen akışı orijinal biçimine geri aktarır.

rsMacOS'ta varsayılan olarak yüklüdür. Linux sistemlerinde kurmanız gerekebilir - örn.

sudo apt install rs

Uyarı: stdbufve sorts -Vseçenek GNU özgü yani değiştirilmemiş MacOS üzerinde çalışma olmaz.


0

GNU'nuz varsa awk, bunu deneyebilirsiniz:

NR == 1 {
    for (i = 2; i <= NF; i++) {
        columns[substr($i, 2)] = i;
    }
    count = asorti(columns, sorted, "@ind_num_asc");
    printf("%s", $1);
    for (i = 1; i <= count; i++) {
        printf(" M%s", sorted[i]);
        indx[i] = columns[sorted[i]];
    }
    print "";
    next;
}
{
    printf("%s", $1);
    for (i = 1; i <= count; i++) {
        printf(" %s", $(indx[i]));
    }
    print "";
}

0

Python'da:

from csv import DictReader, DictWriter
with open('in_file.csv') as infile, open('out_file.csv') as outfile:
  reader = DictReader(infile)
  writer = DictReader(outfile, fieldnames=sorted(reader.fieldnames))
  writer.writerows(reader)

0

Bunu iyi bir cevap olarak kabul edip etmediğinizi bilmiyorum, ama ...

Neden bu sorunu çözmek için bir veritabanı kullanmıyorsunuz? veri kümenizi geçici bir tablo olarak içe aktarabilir ve ardından

SELECT sütun1, sütun2, ... sütun-n FROM my_temp_table

İhtiyacınız olan başka bir filtre veya dönüşüm kullanabilirsiniz. Ardından, çıktılarınızı istediğiniz gibi yeniden biçimlendirebilirsiniz.

Tüm bu görevler bir bash betiği ve çıktıları kanallar kullanarak zincirleme olarak programlanabilir.

Bazen komutlar arasındaki çıkış ilerlemesini görmek için "pv" komutunu kullandım.

Veri kümesini içe aktarmak için Pentaho Data Integration kullanarak bir ETL programlayabilirsiniz.


0

Belki bu da sana yardımcı olabilir.

  1. İlk önce dosyanızı transpoze edebilirsiniz ( /programming/1729824/an-efficient-way-to-transpose-a-file-in-bash )
  2. İlk sütunu sort komutuyla sıralayın.
  3. Yeniden aktar.

Ör:

$ echo "ID M2 M5 M8 M1 M3 M9 .....M7000000
Animal1 1 0 2 1 0 2 .....1
Animal2 0 1 2 0 1 1 .....0
Animal3 2 1 0 1 2 1 .....0
.
.
.
.
Animaln" | awk '
{ 
    for (i=1; i<=NF; i++)  {
        a[NR,i] = $i
    }
}
NF>p { p = NF }
END {    
    for(j=1; j<=p; j++) {
        str=a[1,j]
        for(i=2; i<=NR; i++){
            str=str" "a[i,j];
        }
        print str
    }
}' | sort -n | awk '
{ 
    for (i=1; i<=NF; i++)  {
        a[NR,i] = $i
    }
}
NF>p { p = NF }
END {    
    for(j=1; j<=p; j++) {
        str=a[1,j]
        for(i=2; i<=NR; i++){
            str=str" "a[i,j];
        }
        print str
    }
}'
ID M1 M2 M3 M5 .....M7000000 M8 M9
Animal1 1 1 0 0 .....1 2 2
Animal2 0 0 1 1 .....0 2 1
Animal3 1 2 2 1 .....0 0 1
.       
.       
.       
.       
Animaln    
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.