Как мне исправить пропущенные значения в цикле for в списке Python?

#python #numpy #for-loop #keras #bioinformatics

#python #numpy #цикл for #keras #биоинформатика

Вопрос:

Я хочу закодировать значение списка Python, чтобы уточнить его, но значение отсутствует в середине моей функции.

Мои среды следующие.

ПК 1 — Windows 10 (64-разрядная версия) без графического процессора, Python 3.6.8 (Anaconda), PyCharm 2018.1.

ПК 2 — Windows 10 (64-разрядная версия) с графическим процессором, Python 3.6.8 (Anaconda), PyCharm 2019.1.

Я хочу получить информацию о последовательности белка из ‘enzyme.txt ‘файл и преобразуйте строковые данные в целочисленный тип. Однако, поскольку последовательность представляет собой строку, я создал функцию для создания и преобразования таблицы словаря, подобной коду, при изменении на целое число. Однако я не знаю, в чем причина, но нет значения, когда i = 860, j = 106 в x [i] [j] Итак, цикл for остановился с ошибкой, приведенной ниже.

 import numpy as np
from keras.utils import np_utils


file = 'enzyme.txt'


def data(file):
    f = open(file, 'r')
    lines = f.readlines()
    seq = []
    ec = []
    for i in range(0, len(lines)):
        lines[i] = lines[i].strip('n')
        seq.append(lines[i][:-2])
        ec.append(lines[i][-1])
    f.close()
    return seq, ec

x, y = data(file)

Amino_Acid_Scalar = {
    'X': 0,
    'A': 1,
    'C': 2,
    'D': 3,
    'E': 4,
    'F': 5,
    'G': 6,
    'H': 7,
    'I': 8,
    'K': 9,
    'L': 10,
    'M': 11,
    'N': 12,
    'P': 13,
    'Q': 14,
    'R': 15,
    'S': 16,
    'T': 17,
    'V': 18,
    'W': 19,
    'Y': 20
}


def amino_acid_to_scalar(amino_acid):
    if not amino_acid in Amino_Acid_Scalar:
        return None
    return Amino_Acid_Scalar[amino_acid]


def sequence_to_scalar(sequence):
    scalar = [amino_acid_to_scalar(amino_acid) for amino_acid in sequence]
    if None in scalar:
        return None
    return scalar


def sequences_to_scalar(sequences):
    scalars = [sequence_to_scalar(sequence) for sequence in sequences]
    return scalars


x = sequences_to_scalar(x)

for i in range(0, len(x)):
    for j in range(0, len(x[i])):
        #print(x[i][j], i, j)
        #tmp = x[i][j]
        #print(tmp)
        #arr[i][j] = tmp
        pass

y = np_utils.to_categorical(y, 7)
x = np.array(x)
y = np.array(y, dtype='int64')
 

В ‘enzyme.txt ‘файл, столбцы с 858 по 862 выглядят следующим образом.

 ATKAVCVLKGDGPVQGIINFEQKESNGPVKVWGSIKGLTEGLHGFHVHEFGDNTAGCTSAGPHFNPLSRKHGGPKDEERHVGDLRNVTADKDGVADVSIEDSVISLSGDHCIIGRTLVVHEKADDLGKGGNEESTKTGNAGSRLACGVIGIAQ,1
ATKAVCVLKGDGPVQGIINFEQKESNGPVKVWGSIKGLTEGLHGFHVHEFGDNTAGCTSAGPHFNPLSRKHGGPKDEERHVGDLRNVTADKDGVADVSIEDSVISLSGDHCIIGRTLVVHEKADDLGKGGNEESTKTGNAGSRLACGVIGIAQ,1
MRVVVIGAGVIGLSTALCIHERYHSVLQPLDIKVYADRFTPLTTTDVAAGLWQPYLSDPNNPQEADWSQQTFDYLLSHVHGCALEAAKLFGRILEEKKLSRMPPSHL,1
MPKFYCDYCDTYLTHDSPSVRKTHCSGRKHKENVKDYYCKWMEEQAQSLIDKTTAAFQQGKIPPTPFSAPPPAGAMIUGGGAAACUCGACUGCAUAAUUUGUGGUAGUGGGGGACUGCGUUCGCGCUUUCCCCUG,1
GPHMSIHSGRIAAVHNVPLSVLIRPLPSVLDPAKVQSLVDTIREDPDSVPPIDVLWIKGAQGGDYFYSFGGSHRYAAYQQLQRETIPAKLVQSTLSDLRVYLGASTPDLQ,1

 

Отображается следующая ошибка.

 Using TensorFlow backend.
Traceback (most recent call last):
  File "C:Program FilesJetBrainsPyCharm 2018.1helperspydevpydev_run_in_console.py", line 53, in run_file
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "C:Program FilesJetBrainsPyCharm 2018.1helperspydev_pydev_imps_pydev_execfile.py", line 18, in execfile
    exec(compile(contents "n", file, 'exec'), glob, loc)
  File "C:/Users/Inyong/Documents/PycharmProjects/Test/Test_4_TXT.py", line 81, in <module>
    for j in range(0, len(x[i])):
TypeError: object of type 'NoneType' has no len()
 

Поэтому, когда я пытаюсь увидеть значение того, где оно остановилось,

 > x[860][106]
 

Я получаю следующую ошибку.

 Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: 'NoneType' object is not subscriptable
 

Я действительно ценю вашу помощь.

Ответ №1:

Вы хорошо отследили проблему. То, что вы видите, есть x = None или x[860]=None потому, что вы не можете иметь None[186] .

Мои предложения по коду в целом:

  • сначала избавьтесь от привычки повторять len(thing) или range(len(thing)) . Потому что ошибки трудно отследить, не так ли :). Посмотрите замечательный доклад на эту тему https://www.youtube.com/watch?v=EnSu9hHGq5o
  • открывать файлы проще с помощью ключевого слова «with» вы увидите его в документации как диспетчер контекста (см. Ниже Пример его использования)
  • Внизу у вас есть код numpy. Хотя я думаю, что это здорово, что вы рассматриваете скорость. Я бы не стал делать ни Numpy, ни Pandas .astype(‘category’) или что-то в этом роде, потому что одна последовательность может состоять из всех букв «L», и в этот момент все они будут равны нулю вместо десяти, как у вас в словаре Amino_Acid_Scalar .
  • Я не знаю, были ли значения Amino_Acid_Scalar выбраны вами или были даны вам, но я бы предложил использовать что-то более простое, например ord(base)-65 , тогда ваше сопоставление будет проще и
  • ваши базы будут хорошо вписываться в массив Numpy с int8 в качестве dtype.

Этот код можно сократить.

 def amino_acid_to_scalar(amino_acid):
    if not amino_acid in Amino_Acid_Scalar:
        return None
    return Amino_Acid_Scalar[amino_acid]
 

Вы можете заменить эту функцию методом «get» по словарю:

 Amino_Acid_Scalar.get(amino_acid, None)
 

где «None» — это значение по умолчанию, которое вы хотите отправить обратно, если нет ключа. (или вы можете использовать сокращенную версию Amino_Acid_scalar.get(amino_acid) , потому что None является возвращаемым значением по умолчанию)

 import numpy as np
from keras.utils import np_utils


Amino_Acid_Scalar = {
    'X': 0,
    'A': 1,
    'C': 2,
    'D': 3,
    'E': 4,
    'F': 5,
    'G': 6,
    'H': 7,
    'I': 8,
    'K': 9,
    'L': 10,
    'M': 11,
    'N': 12,
    'P': 13,
    'Q': 14,
    'R': 15,
    'S': 16,
    'T': 17,
    'V': 18,
    'W': 19,
    'Y': 20
}

file = 'enzyme.txt'

seqs = []
ecs = []


with open(file, 'r') as f:
    for line in f:
        try:
            seq, ec=line.strip().partition(',')[0:3:2]
            seqs.append(seq)
            ecs.append(ec)
        except (ValueError, IndexError) as e:
            print(f'problem was at line {line} with error: {e}')


def sequence_to_scalar(sequence):
    for amino_acid in sequence:
        value = Amino_Acid_Scalar.get(amino_acid, None)
        if value:
            yield value


def sequences_to_scalar(sequences):
    scalars = [sequence_to_scalar(sequence) for sequence in sequences]
    return scalars


scalar_seqs = sequences_to_scalar(seqs)

for count, seq in enumerate(scalar_seqs):
    for count_inner, base in enumerate(seq):
        print(f'{count}, {count_inner}, {base}')
 

Комментарии:

1.Большое вам спасибо за ваш ответ. При использовании измененного кода Seq, ec = line.strip (). Partition (',') on line TypeError: tuple indices must be integers or slices, not tuple произошла ошибка. Итак, я изменил строку следующим образом, но она работает. line = line.strip (' n'); seq = line [: - 2]; ec = line [-1]; seqs.append (seq); ecs.append (ec) . Что вы думаете о моем измененном коде?

2. И я протестировал это, вставив print (count, seq, count_inner, base) в нижнюю часть двойного цикла for. В этом случае я подтвердил, что все четыре переменные являются выходными. После завершения вывода появляется следующая ошибка. for count_inner, base in enumerate (seq): TypeError: 'NoneType' object is not iterable Если я попытаюсь определить a dtype обычным способом, я знаю, как NoneType решить эту ошибку, ошибка, подобная ValueError: setting an array element with a sequence. я хотел бы спросить, есть ли какой-либо другой способ.

3. Мой ответ обновлен: причина, по которой я бы не стал использовать ec = line[-1] что происходит, когда вы получаете 2 значное число в этом поле. (или отрицательный). Используйте силу запятой. это то, для чего он существует. для 2-го вопроса: вы хотели, чтобы None были частью ваших последовательностей, но теперь вам приходится иметь с ними дело. Как насчет их фильтрации? (см. Обновленный код для генератора, использующего yield)

4. Я проверил код, который вы обновили : [0: 3: 2] . Код работает нормально. Я действительно ценю это.