Лучшая стратегия для обработки этого текстового файла в структурированную таблицу? - PullRequest
0 голосов
/ 30 января 2019

Мой соавтор хочет, чтобы я обработал входной текстовый файл в структурированную таблицу:

Необработанный текстовый файл ввода выглядит как

PMID    22224631
Title    -765 G_C and -1195 A_G promoter variants of the cyclooxygenase-2 gene decrease the risk for preeclampsia.
Found 8 gene(s) 
Gene     CRP Mentions
Gene     GC Mentions
Gene     PTGS2 Mentions
Found 1 variant(s)  
Variant  I399V URL
Gene     PTGS1 Mentions
Found 2 variant(s)  
Variant  L255L URL
Variant  V255V URL
Gene     CT49 Mentions
Gene     GAA Mentions
Found 1 variant(s)  
Variant  Q255H URL
Gene     CGA Mentions
Gene     TAT Mentions

PMID    16076618
Title    1166C mutation of angiotensin II type 1 receptor gene is correlated with umbilical blood flow velocimetry in women with preeclampsia.
Found 13 gene(s)    
Gene     AGTR2 Mentions
Gene     QTRT1 Mentions
Gene     SLC25A10 Mentions
Gene     ATM Mentions
Gene     PIH Mentions
Gene     CCL14 Mentions
Gene     AGT Mentions
Gene     REN Mentions
Gene     ASAH1 Mentions
Gene     AGTR1 Mentions
Gene     SSD Mentions
Gene     TAT Mentions
Found 1 variant(s)  
Variant  D389A URL
Gene     ACE Mentions
Found 2 variant(s)  
Variant  D389A URL
Variant  H389P URL

Вы можете видеть, для каждого PMID (id для научной публикации), есть некоторая информация о генах, для каждого гена может быть некоторая информация о вариантах.Входной текст во многом похож на вывод функции «печать» вместо таблицы.Затем каждый блок PMID отделяется пустой строкой.

Финальная таблица, которую хочет сотрудничать, похожа на таблицу длинного формата (.csv), состоящую из трех слоев: PMID, ген и вариант.PMID содержит гены, гены содержат (или нет) варианты.Возьмите приведенный выше пример входного файла:

PMID     |   Gene   |  Variant
22224631 |   CRP    | No
22224631 |   GC     | No
22224631 |   PTGS2  | I399V 
22224631 |   PTGS1  | L255L 
22224631 |   PTGS1  | V255V 
22224631 |   CT49   | No 
22224631 |   GAA    | Q255H
.......  |  .....

У меня нет большого опыта обработки необработанного текстового файла в таблицах на Python.

Мое мышление заключается в использовании регулярных выражений для удаления лишних слов в первую очередь.Я пытаюсь прочитать в этом текстовом файле, он генерирует большой список строк, в котором каждая строка является строкой во входном файле

with open ("gene and variants.txt", "r") as myfile:
    data=myfile.readlines()

data2 = [x for x in data if not x.startswith('Title') and not 
x.startswith('Found')]
data3 = [x for x in data2 if x != " \t\n"]
data4 = [x.strip(" Mentions\n") for x in data3]
data4 = [x.strip(" URL") for x in data4]
data4 = [x.replace("Gene\t", "Gene") for x in data4]
data4 = [x.replace("PMID\t", "PMID ") for x in data4]
data4 = [x.replace("Variant\t", "Variant") for x in data4]

К счастью, я могу удалить самую ненужную информацию, наконец, добраться доэтот список строк:

Список строк примерно такой:

The list of string like this

Тогда я застрял .... что делатьзатем преобразовать этот список строк в мою целевую таблицу?Я думал использовать Pandas, но кажется, что каждая строка в кадре данных принимает только одну строку с одним столбцом.

Я на правильном пути?Если да, что мне делать дальше?

Если нет, есть ли у вас какие-либо предложения относительно того, как мне следует подойти к этой проблеме?

Ответы [ 3 ]

0 голосов
/ 30 января 2019

Вы можете работать со словарями.

Например:

fileDict =  {Gene : [], Variant: [], PMID: []}

Выполнить итерацию по списку и проверить, есть ли Gene, Variant или PMID и добавить значения.

Затем вы можете сделать как

for x in fileDict['Gene']:
    print(x)
0 голосов
/ 30 января 2019

Вы можете выполнить следующие шаги, чтобы преобразовать ваш текстовый файл в фрейм данных Pandas в нужном формате:

  1. Используйте read_csv() для импорта текстового файла.Чтобы проверить, я скопировал необработанный исходный текст, который вы вставили выше, в новый текстовый файл и сохранил его как raw_input.txt:
df = pd.read_csv('raw_input.txt', header=-1)

Кадр данных будет содержать набор строк, отформатированных какэто:

    0
0   PMID 22224631
1   Title -765 G_C and -1195 A_G promoter varia...
2   Found 8 gene(s)
3   Gene CRP Mentions
4   Gene GC Mentions
5   Gene PTGS2 Mentions
6   Found 1 variant(s)
7   Variant I399V URL
8   Gene PTGS1 Mentions
...
Наш следующий шаг - создать словарь, в котором будет храниться информация для каждого PMID:
# Get the indices of each row that has a new PMID header
pmid_idxs = df[df[0].str.contains('PMID')].index

# Now construct the dictionary, using each PMID as a key and 
# filling the entry for each key with the PMID's gene info.
pmid_dict = {}
for i, val in enumerate(pmid_idxs.values):
    if pmid_idxs.values[-1] != val:
        nxt_pmid_idx = pmid_idxs.values[i+1]
        pmid_dict[df[0].iloc[val]] =  df[0].iloc[val+1:nxt_pmid_idx].reset_index(drop=True)
    else: # if last PMID
        pmid_dict[df[0].iloc[val]] =  df[0].iloc[val+1:].reset_index(drop=True)
Теперь по основной части - это логика, которая будет циклически проходить через каждую запись в словаре, извлекать и форматировать информацию о генах каждого PMID в небольшой кадр данных и добавлять этот кадр данных в список:
df_list = []

for key, value in pmid_dict.items():
    pmid_num = ''.join(c for c in key if c not in 'PMID ')
    series = value
    next_rows = series.shift(-1).fillna('placeholder')
    df_dict = {'PMID': [],
               'Gene': [],
               'Variant': []}
    gene = ''
    variant = ''
    for i, row in series.iteritems():
        if 'Gene' in row:
            gene = row[4:-9].strip(' ')
            if i <= (len(series)) and 'variant' not in next_rows.iloc[i].lower():
                df_dict['PMID'].append(pmid_num)
                df_dict['Gene'].append(gene)
                df_dict['Variant'].append('No')
            elif i == len(series) + 1:
                df_dict['PMID'].append(pmid_num)
                df_dict['Gene'].append(gene)
                df_dict['Variant'].append('No')
        if 'Variant' in row:
            variant = row[8:-4].strip(' ')
            df_dict['PMID'].append(pmid_num)
            df_dict['Gene'].append(gene)
            df_dict['Variant'].append(variant)

    df = pd.DataFrame(df_dict)
    df_list.append(df)
Конечный выходной фрейм данных будет просто конкатенацией каждого небольшого фрейма данных, который мы создали выше:
output_df = pd.concat(df_list).reset_index(drop=True)

И это все.Выходной фрейм данных выглядит следующим образом, и я считаю, что это ваш желаемый формат:

    PMID        Gene      Variant
0   22224631    CRP       No
1   22224631    GC        No
2   22224631    PTGS2     I399V
3   22224631    PTGS1     L255L
4   22224631    PTGS1     V255V
5   22224631    CT49      No
6   22224631    GAA       Q255H
7   22224631    CGA       No
8   22224631    TAT       No
9   16076618    AGTR2     No
10  16076618    QTRT1     No
11  16076618    SLC25A10  No
12  16076618    ATM       No
13  16076618    PIH       No
14  16076618    CCL14     No
15  16076618    AGT       No
16  16076618    REN       No
17  16076618    ASAH1     No
18  16076618    AGTR1     No
19  16076618    SSD       No
20  16076618    TAT       D389A
21  16076618    ACE       D389A
22  16076618    ACE       H389P
0 голосов
/ 30 января 2019

Я не очень опытен в Python, но мой подход заключается в создании кортежей.
Сначала создайте вручную, чтобы сделать эту первую PMID | Gene | Variant деталь,
, затем с помощью регулярных выражений уберите лишний текст и добавьтеэти кортежи в одном списке.
Затем распечатайте их все, используя форматирование строк.
Или вы можете создать 3 списка, один для PMID, один для Джина, один для Варианта.Затем итерируйте их с помощью forloop и распечатывайте их, чтобы создать эту таблицу.
Извините за невозможность дать конкретные советы.
С наилучшими пожеланиями!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...