【问题标题】:pandas reading a text file generated from dataframe.to_string熊猫读取从 dataframe.to_string 生成的文本文件
【发布时间】:2017-03-23 20:31:43
【问题描述】:

我有一个包含此表的文本文件:

                   Ion  TheoWavelength         Blended_Set  
Line_Label                                                                                                                                             
H1_4340A    Hgamma_5_2        4340.471                None
He1_4472A     HeI_4471        4471.479                None
He2_4686A    HeII_4686        4685.710                None
Ar4_4711A       [ArIV]        4711.000                None
Ar4_4740A       [ArIV]        4740.000                None
H1_4861A     Hbeta_4_2        4862.683                None

此表是使用 dataframe.to_string 从 pandas 数据帧生成的,然后保存 unicode 变量。

我想使用 pandas 函数从这个文件创建一个数据框:

import pandas as pd
df = pd.read_csv('my_table_file.txt', delim_whitespace = True, header = 0, index_col = 0)

但是我得到了这个错误

Traceback (most recent call last):
  File 
    df = pd.read_csv(table, delim_whitespace = True, header = 0, index_col = 0)
  File "/home/user/anaconda/python2/lib/python2.7/site-packages/pandas/io/parsers.py", line 562, in parser_f
    return _read(filepath_or_buffer, kwds)
  File "/home/user/anaconda/python2/lib/python2.7/site-packages/pandas/io/parsers.py", line 325, in _read
    return parser.read()
  File "/home/user/anaconda/python2/lib/python2.7/site-packages/pandas/io/parsers.py", line 815, in read
    ret = self._engine.read(nrows)
  File "/home/user/anaconda/python2/lib/python2.7/site-packages/pandas/io/parsers.py", line 1314, in read
    data = self._reader.read(nrows)
  File "pandas/parser.pyx", line 805, in pandas.parser.TextReader.read (pandas/parser.c:8748)
  File "pandas/parser.pyx", line 827, in pandas.parser.TextReader._read_low_memory (pandas/parser.c:9003)
  File "pandas/parser.pyx", line 881, in pandas.parser.TextReader._read_rows (pandas/parser.c:9731)
  File "pandas/parser.pyx", line 868, in pandas.parser.TextReader._tokenize_rows (pandas/parser.c:9602)
  File "pandas/parser.pyx", line 1865, in pandas.parser.raise_parser_error (pandas/parser.c:23325)
pandas.io.common.CParserError: Error tokenizing data. C error: Expected 3 fields in line 3, saw 4

我敢说这是由于索引列名称在它自己的行中引起的。

有没有办法避免这个问题或者导出表格而不包含这个标签?

附:我尝试使用 dataframe.to_csv 表,但据我所知,如果它们具有不同的 dtype,它不允许您使用表列格式

【问题讨论】:

    标签: python csv pandas dataframe


    【解决方案1】:

    在这种情况下,我会使用 HDF5 格式 - 它会处理您的索引。

    除了比 CSV 快得多之外,您还可以有条件地选择数据(如使用 SQL DB),它支持压缩等。

    演示:

    In [2]: df
    Out[2]:
                       Ion  TheoWavelength Blended_Set
    Line_Label
    H1_4340A    Hgamma_5_2        4340.471        None
    He1_4472A     HeI_4471        4471.479        None
    He2_4686A    HeII_4686        4685.710        None
    Ar4_4711A       [ArIV]        4711.000        None
    Ar4_4740A       [ArIV]        4740.000        None
    H1_4861A     Hbeta_4_2        4862.683        None
    
    In [3]: df.to_hdf('d:/temp/myhdf.h5', 'df', format='t', data_columns=True)
    
    In [4]: x = pd.read_hdf('d:/temp/myhdf.h5', 'df')
    
    In [5]: x
    Out[5]:
                       Ion  TheoWavelength Blended_Set
    Line_Label
    H1_4340A    Hgamma_5_2        4340.471        None
    He1_4472A     HeI_4471        4471.479        None
    He2_4686A    HeII_4686        4685.710        None
    Ar4_4711A       [ArIV]        4711.000        None
    Ar4_4740A       [ArIV]        4740.000        None
    H1_4861A     Hbeta_4_2        4862.683        None
    

    您甚至可以像 SQL DB 一样查询您的 HDF5 文件:

    In [20]: x2 = pd.read_hdf('d:/temp/myhdf.h5', 'df', where="TheoWavelength > 4500 and Ion == '[ArIV]'")
    
    In [21]: x2
    Out[21]:
                   Ion  TheoWavelength Blended_Set
    Line_Label
    Ar4_4711A   [ArIV]          4711.0        None
    Ar4_4740A   [ArIV]          4740.0        None
    

    【讨论】:

    • 非常感谢您的回复。 SQL 功能非常有趣,而且运行良好……但是,对于这种情况,它必须是一个文本文件。我设法让它在“read_csv”中添加任何以“L”开头的行作为注释(这在此数据中不是问题)。我曾尝试使用ignore_rows,但如果您设置列索引,它就不起作用......这很奇怪......
    【解决方案2】:

    考虑 Python 的内置 StringIO,从 Python 3 开始的 io 模块的方法(StringIO 在 Python 2 中作为其自己的模块)从标量字符串中读取文本。在 pandas 的 read_table() 中调用它,然后操作标题的第一行字符串内容:

    from io import StringIO
    import pandas as pd
    
    data = '''
                       Ion  TheoWavelength         Blended_Set
    Line_Label
    H1_4340A    Hgamma_5_2        4340.471                None
    He1_4472A     HeI_4471        4471.479                None
    He2_4686A    HeII_4686        4685.710                None
    Ar4_4711A       [ArIV]        4711.000                None
    Ar4_4740A       [ArIV]        4740.000                None
    H1_4861A     Hbeta_4_2        4862.683                None
    '''
    
    df = pd.read_table(StringIO(data), sep="\s+", header=None, skiprows=3, index_col=0)
    
    headers = [item for line in data.split('\n')[0:3] for item in line.split()][0:4]
    df.columns = headers[0:3]
    df.index.name = headers[3]
    

    如果你需要从文件中读取,使用read_table从文件中读取,然后读取文本文件提取标题:

    df = pd.read_table("DataframeString.txt", sep="\s+", header=None, skiprows=3, index_col=0)
    
    data = []
    with open("DataframeToString.txt", 'r') as f:
        data.append(f.read().split())
    
    df.index.name = data[0][3]
    df.columns = data[0][0:3]
    
    print(df)
    #                    Ion  TheoWavelength Blended_Set
    # Line_Label                                        
    # H1_4340A    Hgamma_5_2        4340.471        None
    # He1_4472A     HeI_4471        4471.479        None
    # He2_4686A    HeII_4686        4685.710        None
    # vAr4_4711A      [ArIV]        4711.000        None
    # Ar4_4740A       [ArIV]        4740.000        None
    # H1_4861A     Hbeta_4_2        4862.683        None
    

    【讨论】:

    • 非常感谢您的回复,但有一个问题:如果您在文本文件中有“数据”,您需要打开文件两次(例如使用 readlines)还是可以直接完成?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-31
    • 2020-04-17
    • 2017-10-21
    • 2021-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多