跳过未知行数来读取标题python pandas

时间:2015-12-01 19:29:21

标签: python pandas

我有一个我用python pandas读到的excel数据:

import pandas as pd
data = pd.read_csv('..../file.txt', sep='\t' )

模拟数据如下所示:

unwantedjunkline1
unwantedjunkline2
unwantedjunkline3
 ID     ColumnA     ColumnB     ColumnC
 1         A          B            C
 2         A          B            C
 3         A          B            C
...

这种情况下的数据在击中标题之前包含3条垃圾线(我不想读入的行),有时它包含4条或更多条垃圾线。所以在这种情况下我读了数据:

data = pd.read_csv('..../file.txt', sep='\t', skiprows = 3 )

数据如下:

 ID     ColumnA     ColumnB     ColumnC
 1         A          B            C
 2         A          B            C
 3         A          B            C
...

但每次不需要的行数不同时,是否有办法使用pandas读取表文件而不使用'skiprows =',而是使用一些匹配标题的命令,以便它知道从头部开始阅读?所以我不必单击打开文件来计算每次文件包含多少不需要的行,然后手动更改'skiprows ='选项。

2 个答案:

答案 0 :(得分:7)

如果你知道标题的开头是什么:

def skip_to(fle, line,**kwargs):
    if os.stat(fle).st_size == 0:
        raise ValueError("File is empty")
    with open(fle) as f:
        pos = 0
        cur_line = f.readline()
        while not cur_line.startswith(line):
            pos = f.tell()
            cur_line = f.readline()
        f.seek(pos)
        return pd.read_csv(f, **kwargs)

演示:

In [18]: cat test.txt
1,2
3,4
The,header
foo,bar
foobar,foo
In [19]: df = skip_to("test.txt","The,header", sep=",")

In [20]: df
Out[20]: 
      The header
0     foo    bar
1  foobar    foo

通过调用.tell,我们可以跟踪指针在前一行的位置,因此当我们点击标题时,我们会回到该行并将文件对象传递给pandas。

或者使用垃圾,如果他们都是从一些共同点开始的话:

def skip_to(fle, junk,**kwargs):
    if os.stat(fle).st_size == 0:
        raise ValueError("File is empty")
    with open(fle) as f:
        pos = 0
        cur_line = f.readline()
        while cur_line.startswith(junk):
            pos = f.tell()
            cur_line = f.readline()
        f.seek(pos)
        return pd.read_csv(f, **kwargs)

 df = skip_to("test.txt", "junk",sep="\t")

答案 1 :(得分:1)

另一种实现动态跳过的简单方法对我有用:

# Open the file
with open('test.csv', encoding='utf-8') as readfile:
        ls_readfile = readfile.readlines()
        
        #Find the skiprows number with ID as the startswith
        skip = next(filter(lambda x: x[1].startswith('ID'), enumerate(ls_readfile)))[0]
        print(skip)

#import the file with the separator \t
df = pd.read_csv(r'test.txt', skiprows=skip, sep ='\t')