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)