заполнить пробелы при объединении данных в python

вот моя проблема: я начинаю с нескольких матриц, в которые извлекаются данные для построения новой и общей матрицы. Первым шагом является чтение входных файлов с помощью модуля csv и извлечение значений «позиции» (хранящихся в строке [1]), которые будут использоваться в качестве заголовков столбцов в окончательной матрице. Каждый файл содержит подмножество общих «позиций», которые иногда присутствуют более чем в одном файле. Итак, я прежде всего строю упорядоченный список (от меньшего к большему целому) из слияния всех значений «позиции», игнорируя повторяющиеся. Вот как я это делаю:

for infile in glob.glob('passed_*.vcf'):
    infilen=open(infile)
    inf = csv.reader(infilen,delimiter='\t')
    for row in inf:
        if row[1] in pos:
            continue
        else:
            pos.append(row[1])
    infilen.close()
pos.sort(key=int)
head=str('\t'.join(pos))
of=open('trial.txt', 'a')   
print>>of,head

Сделав это, я возвращаюсь к исходным файлам и читаю другое значение (на этот раз в строке [3]), которое я хочу добавить под соответствующим заголовком, созданным выше (то есть «позицией»). Поскольку каждый файл имеет подмножество общих позиций, мне придется заполнить пробелы, когда конечная позиция матрицы (хранящаяся в списке «pos») отсутствует в строке [1] отдельного файла. Вот код, который я пытаюсь:

for infile in glob.glob('passed_*.vcf'):
    infilen=open(infile)
    inf = csv.reader(infilen,delimiter='\t')
    seq=[]
    for row in inf:
        if row[1] in pos:
            seq.append(row[3])  
        else:
            seq.append('N')

Излишне говорить, что я застрял. Я думал использовать цикл while, но, поскольку я не очень опытен, я прошу у вас совета любого рода.

Пример данных

ввод (образец 1):

1   2025    blah    A   .   blah    PASS    AC=0    GT:DP   0/0:61
2   2027    blah    C   .   blah    blah    AC=0    GT:DP   0/0:61
3   2028    blah    T   .   blah    PASS    AC=0    GT:DP   0/0:61

ввод (образец n):

1   2025    blah    G   .   blah    PASS    AC=0    GT:DP   0/0:61
2   2026    blah    A   .   blah    blah    AC=0    GT:DP   0/0:61
3   3089    blah    T   .   blah    PASS    AC=0    GT:DP   0/0:61

вывод (одна матрица с входной строкой [1] в качестве переменных и строкой [3] в качестве значений. каждая строка представляет собой отдельный образец, т. е. другой входной файл):

          2025    2026    2027    2028  ...  3089
sample1    A       NaN     C       T         NaN
samplen    G        A     NaN     NaN         T

person cometarossa    schedule 14.05.2012    source источник
comment
Вероятно, вы захотите использовать pandas для загрузки, слияния, нарезки и нарезки. ваши матрицы.   -  person Maxim Egorushkin    schedule 14.05.2012
comment
Спасибо, я уже знал об этом, но поскольку я пришел к этому моменту (что, поверьте мне, для моих навыков Python действительно интересно), я искал независимый способ завершить свой код.   -  person cometarossa    schedule 14.05.2012
comment
Не могли бы вы добавить короткие примеры (по крайней мере, 2 образца vcf и желаемый результат)? Будет намного проще понять, что вы хотите сделать...   -  person Emmanuel    schedule 14.05.2012


Ответы (1)


>>> from collections import defaultdict
>>> import glob
>>> pos = defaultdict(dict)
>>> for index, infile in enumerate(glob.glob('D:\\DATA\\FP12210\\My Documents\\Temp\\Python\\sample*.vcf'), 1):
    for line in open(infile):
        # Convert value in integer already
        val, letter = int(line.split()[1]), line.split()[3]
        pos[val][index] = letter


>>> def print_pos(pos):
    """ Formats pos """
    # Print header by sorting keys of pos
    values = sorted(pos.keys())
    print '          ',
    for val in range(values[0], values[-1] + 1):
        print '{0:5}'.format(val),
    print

    # pos has keys according to row1, create pos2 with keys = sample #
    pos2 = defaultdict(dict)
    for val, d in pos.iteritems():
        for index, letter in d.iteritems():
            pos2[index][val] = letter

    # Now easier to print lines
    for index in sorted(pos2.keys()):
        print ' sample{0:2} '.format(index),
        for val in range(values[0], values[-1] + 1):
            if val in pos2[index]:
                print '   {0} '.format(pos2[index][val]),
            else:
                print ' NaN ',
        print


>>> print_pos(pos)
            2025  2026  2027  2028  2029  2030  2031  2032
 sample 1     A   NaN     C     T   NaN   NaN   NaN   NaN 
 sample 2     G     A   NaN   NaN   NaN   NaN   NaN     T 
>>> 

Я использую pos для сбора значений, я также использую pos2, который содержит одни и те же данные, упорядоченные по-разному для целей печати, потому что:

  • pos ориентирован на ценность, полезно иметь диапазон значений
  • pos2 ориентирован на выборку, полезно иметь значения, заданные номером выборки

Чтобы не иметь слишком большой диапазон, я использовал значения:

-sample1.vcf:

1   2025    blah    A   .   blah    PASS    AC=0    GT:DP   0/0:61
2   2027    blah    C   .   blah    blah    AC=0    GT:DP   0/0:61
3   2028    blah    T   .   blah    PASS    AC=0    GT:DP   0/0:61

-sample2.vcf:

1   2025    blah    G   .   blah    PASS    AC=0    GT:DP   0/0:61
2   2026    blah    A   .   blah    blah    AC=0    GT:DP   0/0:61
3   2032    blah    T   .   blah    PASS    AC=0    GT:DP   0/0:61
person Emmanuel    schedule 15.05.2012
comment
Спасибо, Эммануэль, раньше я не думал о словарном подходе. Я протестирую это решение с огромным объемом данных, с которыми я имею дело. - person cometarossa; 15.05.2012