Pandas read_csv,头名中带有分隔符

pn9klfpd  于 2023-09-29  发布在  其他
关注(0)|答案(3)|浏览(120)

我有一个类似这样的文本文件:

@ some comment
@ some comment
@ [...]
@ some comment
* NAME   S    BX    BY
bla foo bar foo  
"ACF" 1  2  3
"BGB" 4  5  6
"CSD" 7  8  9

我使用下面的代码读入文件。自动检测标题似乎是不可能的,因为第一个字段* NAME在其名称中包含列分隔符。

import pandas as pd

df=pd.read_csv('test.txt',sep="\s+|\t+|\s+\t+|\t+\s+",names=["Name","S","BX","BY"],skiprows=4)

1.如何自动检测标题名称?
1.如何删除标题下的注解和bla...行?

ffscu2ro

ffscu2ro1#

对于您的 * 特定 * 示例,您可以这样做:

df = pd.read_csv('test.txt',sep='\s\s+|(?<=")\s',skiprows=4,engine='python').dropna()

它使用多个空格的分隔符(适用于头部和大部分数据)或前面带双引号的空格(适用于"ABC"值)。
由于bla foo bar foo行在使用该分隔符时只有一个值,因此我们可以使用dropna删除它。
示例输入的输出:

* NAME    S   BX   BY
1  "ACF"  1.0  2.0  3.0
2  "BGB"  4.0  5.0  6.0
3  "CSD"  7.0  8.0  9.0
zbdgwd5y

zbdgwd5y2#

要自动检测头名称并清除不必要的行,可以逐行分析文件,确定所需的行,然后创建DataFrame

import pandas as pd
import re

filename = 'test.txt'

def parse_file(filename):
    with open(filename, 'r') as file:
        lines = file.readlines()

    data_lines = [line.strip() for line in lines if not line.startswith('@') and not line.startswith('bla')]

    header_line = next(line for line in data_lines if line.startswith('*'))
    columns = re.split('\s+', header_line.strip('*').strip())[0:]  
    print(columns)
    
    data_lines.remove(header_line)
    
   
    data = [re.split('\s+', line) for line in data_lines]
    
    df = pd.DataFrame(data, columns=columns)
    
    return df

df = parse_file(filename)

print(df)

最终输出

NAME  S BX BY 
"ACF"  1  2  3
"BGB"  4  5  6 
"CSD"  7  8  9
ve7v8dk2

ve7v8dk23#

另一种解决方案-获取所有以*"开头的行,然后使用pd.read_csv

from io import StringIO

with open("your_file.txt", "r") as f:
    lines = []
    for line in map(str.strip, f):
        if line.startswith(("*", '"')):
            lines.append(line)

df = pd.read_csv(
    StringIO("\n".join(lines)),
    sep=r"\s{2,}|(?<=\") ",
    engine="python",
)
print(df)

图纸:

* NAME  S  BX  BY
0  "ACF"  1   2   3
1  "BGB"  4   5   6
2  "CSD"  7   8   9

相关问题