Python: Как выполнить деление в соответствии с его представлением?

Я хотел бы сделать разделение по алфавиту. Приведенный пример, как показано ниже:

Данный двоичный файл представлен в формате csv:

A=1000, C=0100, G=0010, T=0001

binary.csv: CAT, GAA

0,1,0,0,1,0,0,0,0,0,0,1
0,0,1,0,1,0,0,0,1,0,0,0

Файл binary.csv нужно умножить на значения одной строки, находящиеся в файле csv.

single.csv:

0.28,0.22,0.23,0.27,0.12,0.29,0.34,0.21,0.44,0.56,0.51,0.65

Приведенный ниже код выполняет умножение значений в обоих файлах и вывод:

0.22,0.12,0.65
0.23,0.12,0.44

Код

import csv

with open('single.csv', 'rb') as csvfile:
    for row in csv.reader(csvfile, delimiter=','):
        reals = row

with open('binary.csv', 'rb') as csvfile:
    pwreader = csv.reader(csvfile, delimiter=',')

    with open('output.csv','wb') as testfile:
        csv_writer=csv.writer(testfile)
        for row in pwreader:
            result = []            
            for i,b in enumerate(row):
                if b == '1' :
                    result.append(reals[i])
            csv_writer.writerow(result)

У меня есть дополнительный CSV-файл, который я хотел бы выполнить деление для предыдущего вывода и значения, которые делятся по алфавиту:

 A   C   G   T
 0.4,0.5,0.7,0.1
 0.2,0.8,0.9,0.3

значение для CAT делится на 0,5,0,4,0,1, а GAA делится на 0,9,0,2,0,2 соответственно, так что я могу получить совершенно новый результат следующим образом:

 0.44,0.3,6.5
 0.26,0.6,2.2

использование numpy для массива может решить эту проблему, но при использовании более чем с несколькими тысячами данных это может оказаться неприемлемым. Недостаточно памяти произошло, когда я попробовал данные на 60 000++.

Может кто-нибудь мне помочь?

1 ответ

Решение
import numpy as np

Предположим, вы можете извлечь их из файлов:

actg = np.array([
    [0,1,0,0,1,0,0,0,0,0,0,1],
    [0,0,1,0,1,0,0,0,1,0,0,0]
])

single = np.array([0.28,0.22,0.23,0.27,0.12,0.29,0.34,0.21,0.44,0.56,0.51,0.65])

division = np.array([
    [0.4,0.5,0.7,0.1],
    [0.2,0.8,0.9,0.3]
])

Во-первых, давайте получим actg в более полезный формат:

>>> actg = actg.reshape((-1, 3, 4))
array([[[0, 1, 0, 0],
        [1, 0, 0, 0],
        [0, 0, 0, 1]],

       [[0, 0, 1, 0],
        [1, 0, 0, 0],
        [1, 0, 0, 0]]])

Мы делаем то же самое для одного:

>>> single = single.reshape((-1, 4))
array([[ 0.28,  0.22,  0.23,  0.27],
       [ 0.12,  0.29,  0.34,  0.21],
       [ 0.44,  0.56,  0.51,  0.65]])

Теперь наши объекты проиндексированы как:

  • actg[row, col, symbol]
  • single[col, symbol]
  • division[row, symbol]

На данный момент мы просто умножаем и суммируем

>>> res_1 = (single * actg).sum(axis=-1)
array([[ 0.22,  0.12,  0.65],
       [ 0.23,  0.12,  0.44]])

Для деления нам нужно вставить размер, чтобы соответствовать col выше, используя np.newaxis

>>> divide_by = (division[:,np.newaxis,:] * actg).sum(axis=-1)
array([[ 0.5,  0.4,  0.1],
       [ 0.9,  0.2,  0.2]])

Тогда, наконец, мы просто делаем разделение

>>> res2 = res_1 / divide_by
array([[ 0.44      ,  0.3       ,  6.5       ],
       [ 0.25555556,  0.6       ,  2.2       ]])

Бонус одного лайнера:

res2 = (single[np.newaxis,:,:] / division[:,np.newaxis,:] * actg).sum(axis=-1)
Другие вопросы по тегам