【问题标题】:How to convert Wikipedia wikitable to Python Pandas DataFrame?如何将 Wikipedia wikitable 转换为 Python Pandas DataFrame?
【发布时间】:2013-03-30 22:08:08
【问题描述】:

在维基百科中,你可以找到一些有趣的数据进行排序、过滤……

这是一个 wikitable 的示例

{| class="wikitable sortable"
|-
! Model !! Mhash/s !! Mhash/J !! Watts !! Clock !! SP !! Comment
|-
| ION || 1.8 || 0.067 || 27 ||  || 16 || poclbm;  power consumption incl. CPU
|-
| 8200 mGPU || 1.2 || || || 1200 || 16 || 128 MB shared memory, "poclbm -w 128 -f 0"
|-
| 8400 GS || 2.3 || || ||  ||  || "poclbm -w 128"
|-
|}

我正在寻找一种将此类数据导入 Python Pandas DataFrame 的方法

【问题讨论】:

  • 据此:pandas.pydata.org/pandas-docs/dev/dsintro.html#dataframe 可以从以下之一构造 DataFrame:一维 ndarray、列表、字典或系列的字典;二维 numpy.ndarray;结构化或记录ndarray;一系列的;另一个数据框。最简单的是 list/dict 的 dict,但不清楚如何以这种方式强制数据。你有什么想法?

标签: python parsing pandas wiki wikipedia


【解决方案1】:

这是一个使用py-wikimarkupPyQuery 从wikimarkup 字符串中提取所有表格作为pandas DataFrames 的解决方案,忽略非表格内容。

import wikimarkup
import pandas as pd
from pyquery import PyQuery

def get_tables(wiki):
    html = PyQuery(wikimarkup.parse(wiki))
    frames = []
    for table in html('table'):
        data = [[x.text.strip() for x in row]
                for row in table.getchildren()]
        df = pd.DataFrame(data[1:], columns=data[0])
        frames.append(df)
    return frames

给定以下输入,

wiki = """
=Title=

Description.

{| class="wikitable sortable"
|-
! Model !! Mhash/s !! Mhash/J !! Watts !! Clock !! SP !! Comment
|-
| ION || 1.8 || 0.067 || 27 ||  || 16 || poclbm;  power consumption incl. CPU
|-
| 8200 mGPU || 1.2 || || || 1200 || 16 || 128 MB shared memory, "poclbm -w 128 -f 0"
|-
| 8400 GS || 2.3 || || || || || "poclbm -w 128"
|-
|}

{| class="wikitable sortable"
|-
! A !! B !! C
|-
| 0
| 1
| 2
|-
| 3
| 4
| 5
|}
"""

get_tables 返回以下数据帧。

       Model Mhash/s Mhash/J Watts Clock  SP                                     Comment
0        ION     1.8   0.067    27        16        poclbm;  power consumption incl. CPU
1  8200 mGPU     1.2                1200  16  128 MB shared memory, "poclbm -w 128 -f 0"
2    8400 GS     2.3                                                     "poclbm -w 128"

 

   A  B  C
0  0  1  2
1  3  4  5

【讨论】:

    【解决方案2】:

    您可以直接使用 pandas。像这样的...

    pandas.read_html(url, attrs={"class": "wikitable"})

    【讨论】:

      【解决方案3】:

      使用re进行一些预处理,然后使用read_csv将其转换为DataFrame

      table = """{| class="wikitable sortable"
      |-
      ! Model !! Mhash/s !! Mhash/J !! Watts !! Clock !! SP !! Comment
      |-
      | ION || 1.8 || 0.067 || 27 ||  || 16 || poclbm;  power consumption incl. CPU
      |-
      | 8200 mGPU || 1.2 || || || 1200 || 16 || 128 MB shared memory, "poclbm -w 128 -f 0"
      |-
      | 8400 GS || 2.3 || || ||  ||  || "poclbm -w 128"
      |-
      |}"""
      
      data = StringIO(re.sub("^\|.|^!.", "", table.replace("|-\n", ""), flags=re.MULTILINE))
      df = pd.read_csv(data, delimiter="\|\||!!", skiprows=1)
      

      输出:

             Model    Mhash/s   Mhash/J   Watts   Clock    SP                                       Comment
      0        ION         1.8    0.067      27            16          poclbm;  power consumption incl. CPU
      1  8200 mGPU         1.2                     1200    16    128 MB shared memory, "poclbm -w 128 -f 0"
      2    8400 GS         2.3                                                              "poclbm -w 128"
      

      【讨论】:

        【解决方案4】:

        已编辑 - 下面的完整答案。我没有安装 Panda,如果这对你有用,请告诉我。

        from pandas import *
        
        wikitable = '''
        {| class="wikitable sortable"
        |-
        ! Model !! Mhash/s !! Mhash/J !! Watts !! Clock !! SP !! Comment
        |-
        | ION || 1.8 || 0.067 || 27 ||  || 16 || poclbm;  power consumption incl. CPU
        |-
        | 8200 mGPU || 1.2 || || || 1200 || 16 || 128 MB shared memory, "poclbm -w 128 -f 0"
        |-
        | 8400 GS || 2.3 || || ||  ||  || "poclbm -w 128"
        |-
        |}'''
        rows = wikitable.split('|-')
        header = []
        table = []
        for i in rows:
             line = i.strip()
             if line.startswith('!'):
                 header = line.split('!!')
             elif line.startswith('|') and line.strip() != '|}':
                 table.append(line[2:].split('||'))
        
        data = {}
        for i in range(len(header) - 1):
            col = []
            for row in table:
                col.append(row[i])
            data[header[i]] = col
        
        print(data)
        
        df = DataFrame(data)
        

        【讨论】:

        • 好的,我刚刚查看了 Panda 文档(应该先这样做),我明白你现在需要什么。给我五分钟,我就会有一个完美的例子。
        猜你喜欢
        • 2018-01-23
        • 2022-01-23
        • 1970-01-01
        • 2021-06-14
        • 2021-11-06
        • 2017-09-20
        • 2013-05-25
        • 2022-09-29
        • 2017-03-17
        相关资源
        最近更新 更多