पहली पंक्ति के आधार पर कॉलम कैसे छाँटें?


12

मुझे एक बहुत बड़े डेटासेट (१००० लाइन और )००००० कॉलम) के स्तंभों को क्रमबद्ध करना होगा। एक उदाहरण के रूप में, मेरे कॉलम बेतरतीब ढंग से व्यवस्थित हैं: col1 col4 col3 col2 col2, और मुझे इसे सॉर्ट करने की आवश्यकता है।

मैं कुछ आदेशों की कोशिश कर रहा हूं, लेकिन कोई सफलता नहीं।

उदाहरण:

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

इस उदाहरण में, डॉट्स का मतलब है कि मेरे पास बहुत सारे कॉलम और लाइनें हैं। फिर, मुझे स्तंभों को क्रमबद्ध करने की आवश्यकता है जैसे:

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

धन्यवाद


क्या आप डेटा सेट की कुछ पंक्तियों के साथ एक उदाहरण जोड़ सकते हैं?
jcbermu

आपके अपेक्षित परिणाम में केवल पहली पंक्ति है, अन्य मान समान हैं, क्यों?
रोमनपेयररेस्ट

वास्तव में, इसे कॉलम का पालन करने की आवश्यकता है, उदाहरण की गलती थी। क्षमा करें
LLVerardo

पहली पंक्ति के आधार पर पूरे कॉलम को क्रमबद्ध करने की आवश्यकता है।
LLVerardo

2
ट्रांसपोज़, पहले कॉलम के आधार पर छाँटें, वापस ट्रांसपोज़ करें।
सातु कटुरा

जवाबों:


10

GNU datamashऔर GNU के साथ sort:

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

यह "यथोचित छोटे" डेटा के लिए ठीक काम करता है। यह आपकी फ़ाइल के साथ काम कर भी सकता है और नहीं भी।

संपादित करें: ट्रांसपोज़िशन के बिना नीचे दिए गए समाधान कम संसाधन-गहन होने चाहिए।


1
रु आदेश हो सकता है के लिए एक हल्का विकल्प datamashजैसे rs -T < file_in.csv | sort | rs -T -C' '( rsडेबियन-आधारित सिस्टम पर एक पैकेज के रूप में उपलब्ध होना चाहिए)
steeldriver

2
एफडब्ल्यूआईडब्ल्यू, rs("एक डेटा सरणी फिर से खोलें") कुछ बीएसडी के बेस सिस्टम में उपलब्ध है।
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. पहली पंक्ति के लिए, हम संख्यात्मक रूप से इसे 2 क्रमबद्ध करते हैं ... अंतिम कॉलम अपने संख्यात्मक भागों Mका उपयोग करते हुए, शुरुआत में आने वाले अंक के बाद , सुप्रसिद्ध का उपयोग करके Schwartzian maneuver। यह हमें संकेत देता है कि सूचकांकों को पुन: क्रमबद्ध किया गया है ताकि कॉलम संख्यात्मक रूप से क्रमबद्ध क्रम (एम 1, एम 2, एमएक्स, ...) से बाहर आए।
  2. सभी अवशेष तत्वों @Iको फिर से व्यवस्थित करने के लिए आने वाले इन सूचकांकों का उपयोग करना @Fहै।
  3. सरणी को दो-भाग के रूप में असाइन करने से इसे स्ट्रिंग में परिवर्तित किया जाता है जिसमें तत्वों को अलग किया जाता है।
  4. -pपर्ल का विकल्प $_सामग्री के ऑटोप्रिंट को सक्षम करता है , -lजोड़ देगा newline

6

पर्ल मॉड्यूल का उपयोग करें क्रमबद्ध करें :: स्वाभाविक रूप से

इनपुट डेटा

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

उत्पादन

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

सबसे सुरुचिपूर्ण के लिए +1, कॉलम नामों के लिए बहुत विशिष्ट उपसर्ग नहीं मानता, एक पास समाधान।
अरीफ

4

यदि आपके पास rsउपयोगिता स्थापित है, तो आप यह कर सकते हैं:

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

या सभी एक लाइन पर:

rs -c' ' -T | { stdbuf -i0 sed "1q"; sort -V ; } | rs -C' ' -T
  • पहला rsइनपुट डेटा (स्पेस-स्पेरेटेड फ़ील्ड के साथ)
  • कमांड समूह:
    • sedपहली पंक्ति पढ़ता है, इसे आउटपुट करता है, फिर क्विट करता है, बाकी पाइप को rsअछूता छोड़कर । इनपुट बफ़रिंग को बंद करके केवल stdbufयह सुनिश्चित करना आवश्यक है कि sedकेवल पहली नई पंक्ति तक और आगे नहीं पढ़ता है
    • sortशेष लाइनें
  • दूसरा rsपरिणामी धारा को उसके मूल प्रारूप में वापस भेज देता है।

rsMacOS पर डिफ़ॉल्ट रूप से स्थापित है। लिनक्स सिस्टम पर आपको इसे स्थापित करना पड़ सकता है - जैसे

sudo apt install rs

चेतावनी: stdbufऔर sortरों -Vविकल्प जीएनयू-विशिष्ट होते हैं तो असंशोधित MacOS पर काम नहीं करेगा।


0

यदि आपके पास GNU है awk, तो आप यह कोशिश कर सकते हैं:

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

पायथन में:

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

मुझे नहीं पता कि क्या आप इसे एक अच्छा जवाब मानते हैं, लेकिन ...

आप इस समस्या को हल करने के लिए डेटाबेस का उपयोग क्यों नहीं करते हैं? आप अपने डेटासेट को एक अस्थायी तालिका के रूप में आयात कर सकते हैं, और फिर a

कॉलम 1, कॉलम 2, ... कॉलम-एन से my_temp_table का चयन करें

आप एक और फिल्टर, या परिवर्तनों का उपयोग कर सकते हैं जैसे कि आपको ज़रूरत है। फिर, आप अपनी ज़रूरत के अनुसार अपने आउटपुट को पुन: स्वरूपित कर सकते हैं।

इस सभी कार्यों को एक बैश स्क्रिप्ट के रूप में प्रोग्राम किया जा सकता है, और पाइप का उपयोग करके आउटपुट का पीछा करते हुए।

कभी-कभी कमांड के बीच आउटपुट प्रगति देखने के लिए मुझे "pv" कमांड का उपयोग किया जाता है।

डेटासेट आयात करने के लिए आप पेंटाहो डेटा इंटीग्रेशन का उपयोग करके ईटीएल प्रोग्राम कर सकते हैं।


0

शायद यह भी आपकी मदद कर सके।

  1. सबसे पहले आप अपनी फाइल (एक /programming/1729824/an-efficient-way-to-transpose-a-file-in-bash ) का उपयोग कर सकते हैं
  2. सॉर्ट कमांड के साथ पहले कॉलम को सॉर्ट करें।
  3. फिर से संक्रमण।

उदाहरण के लिए:

$ 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    
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.