Python форматирование таблицы через цикл с перечнем направляющих - PullRequest
0 голосов
/ 16 октября 2018

У меня есть список тегов ниже.

mytags = ["a", "b", "c", "d", "e", "f"]

И у меня есть файл со строками, подобными этой, в формате списка.

['a-1',   'b-3',  'c-4',  'e-3']
['a-10', 'b-12', 'c-14', 'd-16']
['b-1',   'c-5', 'd-13',  'f-7']

Я хотел бы напечататьфайл в виде таблицы с разделителями табуляции в порядке тегов в mylist следующим образом.

#header
#a,   b,   c,   d,   e,  f
 a-1  b-3  c-4  NA   e-3 NA
 a-10 b-12 c-14 d-16 NA  NA
 NA   b-1  c-5  d-13 NA  f-7

Я написал код Python, но вложенный двойной цикл дает нежелательный результат.

print (mylist)

for lineList in file:
    for tag in mytags:
        if tag in lineList:
            print(lineList, end="\t")
        else:
            print("NA", end="\t")

Как мне составить таблицу с этими данными?

Ответы [ 4 ]

0 голосов
/ 16 октября 2018

Можно использовать setdefault здесь

my_tags = ["a", "b", "c", "d", "e", "f"]
line_list = [
    ['a-1',   'b-3',  'c-4',  'e-3'],
    ['a-10', 'b-12', 'c-14', 'd-16'],
    ['b-1',   'c-5', 'd-13',  'f-7']
]

for lst in line_list:
    d = {i[0]: i for i in lst}
    for i in my_tags:
        print(d.setdefault(i, 'NA'), end ='\t')
    print()


a-1     b-3     c-4     NA      e-3     NA  
a-10    b-12    c-14    d-16    NA      NA  
NA      b-1     c-5     d-13    NA      f-7 
0 голосов
/ 16 октября 2018

, так как строки будут в файле, поэтому мой подход ниже

# read the file
data = pd.read_csv('test.txt', header=None,sep='[')

master_df = pd.DataFrame(columns=['a','b','c','d','e','f'])

for i in range(len(data)):
    master_df.loc[i] = 'NA'
    temp = data[1][i].replace(']','')
    temp = temp.replace("'",'')
    for char in temp.split(','):
        master_df[char.split('-')[0].strip()][i] = char

print(master_df)

Вывод

      a       b       c      d      e      f
0   a-1     b-3     c-4     NA    e-3     NA
1  a-10    b-12    c-14   d-16     NA     NA
2    NA     b-1     c-5   d-13     NA    f-7
0 голосов
/ 16 октября 2018

Это понятный и простой способ использования re ( Регулярных выражений ) для выполнения того, что вы описали, но вы должны просто получить текст файла без какого-либо специального чтения, такого как csv_reader или чего-либо еще, поэтомупросто прочитайте файл, используя функцию open, давайте начнем: -

import re

filetext = """['a-1',   'b-3',  'c-4',  'e-3']
['a-10', 'b-12', 'c-14', 'd-16']
['b-1',   'c-5', 'd-13',  'f-7']"""

#find all values
values = re.findall(r'\w+-\d+', filetext)
values.sort()

#find tags
tags = []
for i in values:
    if(tags.count(i.split('-')[0])==0):
        tags.append(i.split('-')[0])

#find max length
maxLength = max([len(list(filter(lambda a:a.split('-')[0]==i, values))) for i in tags])

#create a list with the results
result = [[] for i in tags]
ind=-1
for i in tags:
    ind+=1
    for j in values:
        if(j.split('-')[0]==i):
            result[ind].append(j)

#add 'NA' for non complete lists
for i in result:
    i.sort(key=lambda v:int(v.split('-')[1]))
    if(len(i)!=maxLength):
        for j in range(maxLength - len(i)):
            i.append('NA')

#print them as you liked
for i in tags:
    print(i, end='\t')

print()

for i in range(maxLength):
    for j in result:
        print(j[i], end='\t')
    print()

Результат

a      b      c      d       e      f    
a-1    b-1    c-4    d-13    e-3    f-7    
a-10   b-3    c-5    d-16    NA     NA   
NA     b-12   c-14   NA      NA     NA
0 голосов
/ 16 октября 2018

Вы должны извлечь теги из элементов, прежде чем сравнивать их со списком тегов:

mytags = ["a", "b", "c", "d", "e", "f"]
rows = [
    ['a-1',   'b-3',  'c-4',  'e-3'],
    ['a-10', 'b-12', 'c-14', 'd-16'],
    ['b-1',   'c-5', 'd-13',  'f-7']
]
for row in rows:
    for tag in mytags:
        print(row.pop(0) if row and row[0].split('-')[0] == tag else 'NA', end='\t')
    print()

или с выражениями генератора:

print('\n'.join('\t'.join(row.pop(0) if row and row[0].split('-')[0] == tag else 'NA' for tag in mytags) for row in rows))
...