Allineare colonne di testo di dimensioni e contenuto diversi

-1

In un post precedente , ho chiesto dei comandi in < em> Bash per allineare colonne di testo l'una contro l'altra per riga. Mi è diventato chiaro che il compito desiderato (cioè allineare colonne di testo di diverse dimensioni e contenuto per riga) è molto più complesso di quanto inizialmente previsto e che il answer , mentre accettabile per il post precedente, non è sufficiente nella maggior parte dei set di dati empirici. Quindi, vorrei interrogare la comunità sul seguente pseudocodice. In particolare, vorrei sapere se e in che modo il seguente pseudocodice potrebbe essere ottimizzato.

Assumi un file con le colonne n di stringhe. Alcune stringhe potrebbero mancare, altre potrebbero essere duplicate. La colonna più lunga potrebbe non essere la prima elencata nel file, ma deve essere la colonna di riferimento. L'ordine delle righe di questa colonna di riferimento deve essere mantenuto.

> cat file  # where n=3; first row contains column headers
CL1 CL2 CL3
foo foo bar
bar baz qux
baz qux
qux foo
    bar

Tentativo pseudocodice 1 (totalmente inadeguato):

Shuffle columns so that columns ordered by size (i.e., longest column is first in matrix)
Rownames = strings of first column (i.e., of longest column)
For rownames
  For (colname among columns 2:end)
    if (string in current cell == rowname) {keep string in location}
    if (string in current cell != rowname) {
      if (string in current cell == rowname of next row) {add row to bottom of table; move each string of current column one row down}
      if (string in current cell != rowname of next row) {add row to bottom of table; move each string of all other columns one row down}
    }

Ordina le colonne per dimensione:

> cat file_columns_ordered_by_size
CL2 CL1 CL3
foo foo bar
baz bar qux
qux baz 
foo qux 
bar

Output ricercato:

> my_code_here file_columns_ordered_by_size
CL2 CL1 CL3
foo foo 
    bar bar
baz baz    
qux qux qux
foo
bar
    
posta Michael Gruenstaeudl 11.11.2016 - 17:08
fonte

1 risposta

0

Ok. Ci sono voluti più di un'ora di 10 minuti. E i tuoi requisiti non sono stati completamente specificati (che è normale, ma non aspettarti che il risultato sia completo al 100%). Quindi ecco un pezzo di codice per te:

tokens = {'':0}
tokenIndex = 0
tokenList = ['']
def addToken(token):
    global tokenIndex
    global tokenList
    if token == " "*len(token): token = ''
    if token in tokens: return tokens[token]
    tokenList.append(token)
    tokenIndex += 1
    tokens[token] = tokenIndex
    return tokenIndex
headers = []
widths = []
columnKeys = []
usage = []
rows = []
first = True
for line in open ("data"):
    if first:
        first = False
        pos = 0
        for token in line[:-1].split(" "):
            columnKeys.append([])
            headers.append(token)
            widths.append(pos)
            pos += len(token) + 1
            usage.append(0)
        widths.append(pos)
        continue
    column = []
    for i in range(1, len(widths)):
        token = addToken(line[widths[i-1]:widths[i]-1])
        if token != 0: usage[i-1] += 1
        column.append(token)
        columnKeys[i-1].append(token)
    rows.append(column)

leadCol = 1
for i in range(2, len(usage)):
    if usage[i] > leadCol: leadCol = i
sortedUsages = {}
for i in range(len(usage)):
    key = str(usage[i])
    if not key in sortedUsages: sortedUsages[key] = []
    sortedUsages[key].append(i)
sortedKeys = []
for keys in sorted(sortedUsages.keys(), reverse=True):
    for key in keys:
        for idx in sortedUsages[key]:
          sortedKeys.append(idx)

line = headers[sortedKeys[0]]
for i in range(1, len(sortedKeys)):
    line += " " + headers[sortedKeys[i]]
print (line)

for row in rows:
    token = row[sortedKeys[0]]
    mainToken = line = tokenList[token]
    for i in range(1, len(sortedKeys)):
        line += " "
        col = columnKeys[sortedKeys[i]]
        if token in col: line += mainToken
        else: line += " "*len(mainToken)
    print (line)

L'output è

CL2 CL1 CL3
foo foo    
baz baz    
qux qux qux
foo foo    
bar bar bar

che si spera sia un punto di partenza per completare il lavoro.

    
risposta data 12.11.2016 - 14:24
fonte

Leggi altre domande sui tag