【问题标题】:Parsing mixed structured and unstructured data解析混合的结构化和非结构化数据
【发布时间】:2017-07-24 09:46:34
【问题描述】:

我们领域的大量光谱数据、模拟输出文件......来自结构化和非结构化数据的混合体。

一个例子是下面的文件,其中三个点是 代表中间的其他线。

...
...
---------------------------------------------------------------------------------------------------
DGA/MPI-2 Parallel Environment:    4 Molcas's processes are running on   1 node(s) x  4 cores each 
----------------------------------------------------------------------------------------------------
...
...
      Mulliken charges per centre and basis function type
      ---------------------------------------------------

             O1      C2      CR3     O4      CR5     O6      O7      C8      O9      O10     O11     C12
      1s     1.9991  1.9984  2.0000  1.9992  2.0000  1.9986  1.9986  1.9983  1.9993  1.9987  1.9986  1.9983
      2s     1.7994  1.0697  2.0000  1.8080  2.0000  1.8648  1.8692  1.0827  1.7580  1.8781  1.8582  1.0834
      2px    1.9368  0.7559  2.0000  1.9364  2.0000  1.6998  1.6786  0.7228  1.9829  1.6891  1.7016  0.7757
      2pz    1.4406  0.6506  2.0000  1.4297  2.0000  1.7096  1.6791  0.6758  1.4469  1.6580  1.7045  0.6490
      2py    1.7790  0.5652  2.0000  1.7909  2.0000  1.5122  1.5263  0.5719  1.5781  1.4733  1.5474  0.5655
      3s    -0.0040  0.0107  1.9934 -0.0041  1.9932 -0.0093 -0.0095  0.0091 -0.0064 -0.0072 -0.0099  0.0106
      3px   -0.0032  0.0205  1.9939 -0.0031  1.9942 -0.0111 -0.0139  0.0189 -0.0015 -0.0107 -0.0145  0.0460
      3pz   -0.0122 -0.0118  1.9936 -0.0114  1.9936 -0.0077 -0.0073 -0.0072 -0.0102 -0.0070 -0.0076 -0.0035
      3py   -0.0021  0.1446  1.9912  0.0005  1.9919 -0.0113 -0.0112  0.1360 -0.0070 -0.0087 -0.0125  0.1386
      4s     0.0000  0.0000  0.1958  0.0000  0.1914  0.0000  0.0000  0.0000  0.0000  0.0000  0.0000  0.0000
      3d2+   0.0000  0.0000  0.6978  0.0000  0.6939  0.0000  0.0000  0.0000  0.0000  0.0000  0.0000  0.0000
      3d1+   0.0000  0.0000  0.4320  0.0000  0.4423  0.0000  0.0000  0.0000  0.0000  0.0000  0.0000  0.0000

通常某些部分必须手动解析,但如果您到达示例表的开头,则有关表大小的所有信息都在手边,使用成品表阅读器会很棒。问题是,我认识的所有典型读者都不允许给出字节偏移量。 (csv 模块、pandas、numpy)

这导致两种可能的解决方法:

  1. 给出了行偏移。这意味着被调用的 csv 阅读器将从头开始读取整个文件并自行计算换行符。我知道它们通常是用 C 语言实现的,而且速度仍然很快,但我认为丢掉可用信息很难看。
  2. 创建一个字符串并作为StringIO 对象传递给阅读器。

如以下示例代码:

import io
with open('test.log') as f:
    title = 'Mulliken charges per centre and basis function type'
    for line in f: 
        if title == line.strip():
            break
    f.readline()

    known_from_previous_parsing = 18
    mull_charges = ''.join([f.readline() for j in range(known_from_previous_parsing)])
    mull_charges = io.StringIO(mull_charges)
    mull_charges = pd.read_csv(mull_charges, delim_whitespace=True)

第二种方法的问题在于,它将表整体写入内存,从而放弃了自动缓冲的所有优点...... (在你问之前,这不是过早的优化,表可能会变得如此之大,以至于整体读取它们会导致交换。)

所以我的问题是:python 中是否有允许指定字节偏移量的 csv 解析工具。或者更笼统地说,我的方法是否走在正确的轨道上,我应该如何处理结构化和非结构化数据的这种混合?

【问题讨论】:

  • 您可以将fnrows=known_from_previous_parsing 一起传递给read_csv,无需先将其读入内存。
  • 你的目标是什么,pandascsv 或?

标签: python csv parsing


【解决方案1】:

不知道 panda,但是使用 csv 模块,您可以将文件指针(使用 readline()next())前进到表格数据的第一行之前,然后继续任何普通的 csv 文件(假设在表格数据之后没有更多的非结构化文本):

偏移量.dat

This is useles
This is useles
This is useles

Data:
AAA,42
BBB,56
CCC,8878

Python 外壳:

>>> import csv
>>> f = open("offset.dat")
>>> line = f.next()
>>> while not line.startswith("Data:"):
...     line = f.next()
... 
>>> line
'Data:\n'
>>> r = csv.reader(f)
>>> r.next()
['AAA', '42']
>>> r.next()
['BBB', '56']
>>> r.next()
['CCC', '8878']

【讨论】:

    【解决方案2】:

    Pandas 足够聪明地处理这个问题,假设这个内容在文件的末尾。使用skiprows 参数。

    >>> import pandas as pd
    >>> df = pd.read_csv('temp.txt', sep='\s+',skiprows=10)
    >>> df
              O1      C2     CR3      O4     CR5      O6      O7      C8      O9  \
    1s    1.9991  1.9984  2.0000  1.9992  2.0000  1.9986  1.9986  1.9983  1.9993   
    2s    1.7994  1.0697  2.0000  1.8080  2.0000  1.8648  1.8692  1.0827  1.7580   
    2px   1.9368  0.7559  2.0000  1.9364  2.0000  1.6998  1.6786  0.7228  1.9829   
    2pz   1.4406  0.6506  2.0000  1.4297  2.0000  1.7096  1.6791  0.6758  1.4469   
    2py   1.7790  0.5652  2.0000  1.7909  2.0000  1.5122  1.5263  0.5719  1.5781   
    3s   -0.0040  0.0107  1.9934 -0.0041  1.9932 -0.0093 -0.0095  0.0091 -0.0064   
    3px  -0.0032  0.0205  1.9939 -0.0031  1.9942 -0.0111 -0.0139  0.0189 -0.0015   
    3pz  -0.0122 -0.0118  1.9936 -0.0114  1.9936 -0.0077 -0.0073 -0.0072 -0.0102   
    3py  -0.0021  0.1446  1.9912  0.0005  1.9919 -0.0113 -0.0112  0.1360 -0.0070   
    4s    0.0000  0.0000  0.1958  0.0000  0.1914  0.0000  0.0000  0.0000  0.0000   
    3d2+  0.0000  0.0000  0.6978  0.0000  0.6939  0.0000  0.0000  0.0000  0.0000   
    3d1+  0.0000  0.0000  0.4320  0.0000  0.4423  0.0000  0.0000  0.0000  0.0000   
    
             O10     O11     C12  
    1s    1.9987  1.9986  1.9983  
    2s    1.8781  1.8582  1.0834  
    2px   1.6891  1.7016  0.7757  
    2pz   1.6580  1.7045  0.6490  
    2py   1.4733  1.5474  0.5655  
    3s   -0.0072 -0.0099  0.0106  
    3px  -0.0107 -0.0145  0.0460  
    3pz  -0.0070 -0.0076 -0.0035  
    3py  -0.0087 -0.0125  0.1386  
    4s    0.0000  0.0000  0.0000  
    3d2+  0.0000  0.0000  0.0000  
    3d1+  0.0000  0.0000  0.0000  
    

    如果不是,并且您知道或可以计算表格中的行数,那么您仍然可以使用带有rows 参数的此类脚本。

    使用 pandas 读取表格后,您可以将其发送到 csv、sql db、excel 等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-20
      • 2015-10-09
      • 1970-01-01
      • 1970-01-01
      • 2015-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多