Анализ html-таблицы с помощью pd.read_html, где ячейки сами содержат полные таблицы. - PullRequest
1 голос
/ 08 октября 2019

Мне нужно проанализировать таблицу из html, в которой другие таблицы вложены в большую таблицу. Как показано ниже с помощью pd.read_html, каждая из этих вложенных таблиц анализируется и затем «вставляется» / «сцепляется» в виде строк.

Я бы хотел, чтобы каждая из этих вложенных таблиц была проанализирована в свои собственные pd.DataFramesи вставляется как объекты в качестве значения соответствующего столбца.

Если это , а не , возможно, было бы неплохо иметь необработанный HTML-код для вложенной таблицы в виде строки в соответствующей позиции.

Код при проверке:

import pandas as pd
df_up = pd.read_html("up_pf00344.test.html", attrs = {'id': 'results'})

Снимок экрана: Screenshot of table as parsed

Снимок экрана таблицы, отображаемой в формате html: Screenshot of table as html

Ссылка на файл: https://gist.github.com/smsaladi/6adb30efbe70f9fed0306b226e8ad0d8#file-up_pf00344-test-html-L62

1 Ответ

2 голосов
/ 08 октября 2019

Вы не можете использовать read_html для чтения вложенных таблиц, но вы можете свернуть свой собственный html-ридер и использовать read_html для ячеек таблицы:

import pandas as pd
import bs4

with open('up_pf00344.test.html') as f:
    html = f.read()
soup = bs4.BeautifulSoup(html, 'lxml')
results = soup.find(attrs = {'id': 'results'})

# get first visible header row as dataframe headers
for row in results.thead.find_all('tr'):
    if 'display:none' not in row.get('style',''):
        df = pd.DataFrame(columns=[col.get_text() for col in row.find_all('th')])
    break

# append all table rows to dataframe
for row in results.tbody.find_all('tr', recursive=False):
    if 'display:none' in row.get('style',''):
        continue
    df_row = []
    for col in row.find_all('td', recursive=False):
        table = col.find_all('table')
        df_row.append(pd.read_html(str(col))[0] if table else col.get_text())
    df.loc[len(df)] = df_row

Результатdf.iloc[0].map(type):

                                                            <class 'str'>
Entry                                                       <class 'str'>
Organism                                                    <class 'str'>
Protein names                                               <class 'str'>
Gene names                                                  <class 'str'>
Length                                                      <class 'str'>
Cross-reference (Pfam)                                      <class 'str'>
Cross-reference (InterPro)                                  <class 'str'>
Taxonomic lineage IDs                                       <class 'str'>
Subcellular location [CC]                                   <class 'str'>
Signal peptide                                              <class 'str'>
Transit peptide                                             <class 'str'>
Topological domain                  <class 'pandas.core.frame.DataFrame'>
Transmembrane                       <class 'pandas.core.frame.DataFrame'>
Intramembrane                       <class 'pandas.core.frame.DataFrame'>
Sequence caution                                            <class 'str'>
Caution                                                     <class 'str'>
Taxonomic lineage (SUPERKINGDOM)                            <class 'str'>
Taxonomic lineage (KINGDOM)                                 <class 'str'>
Taxonomic lineage (PHYLUM)                                  <class 'str'>
Cross-reference (RefSeq)                                    <class 'str'>
Cross-reference (EMBL)                                      <class 'str'>
e                                                           <class 'str'>

Бонус: поскольку строки вашей таблицы имеют id, вы можете использовать его как индекс вашего фрейма данных df.loc[row.get('id')] = df_row вместо df.loc[len(df)] = df_row.

...