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

12 人关注

我有一个EXCEL数据,我用Python pandas读进去。

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

但每次不需要的线的数量都不同有什么办法可以在不使用'skiprows='的情况下用pandas读入一个表格文件,而是使用一些与文件头相匹配的命令,这样它就知道从文件头开始读了? 这样我就不用每次都要点击打开文件来计算文件中包含多少不需要的行,然后再手动改变'skiprows='选项。

4 个评论
只要自己跳过这几行,传递一个文件对象即可
@Padraic Cunningham 对不起,我没有关注。
使用 open 来拥有一个文件对象,遍历你的文件对象,直到你达到你的垃圾的末端(你必须找出如何评估这个),然后将文件对象传入 pd.read_csv(fileobject, ..) ,而不是你的文件路径。
@Jessica,我添加了一个答案,一旦你知道了标题,那么你只需将其传递给函数,与readline和tell有关的逻辑是最重要的,你可以做任何你想做的事,例如接受更多的args或只使用逻辑,这只是一个例子。
python
pandas
Jessica
Jessica
发布于 2015-12-02
2 个回答
Padraic Cunningham
Padraic Cunningham
发布于 2021-06-25
已采纳
0 人赞同

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

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)

Demo:

In [18]: cat test.txt
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")
    
@Jessica,因为你需要传递 sep="\t" ,我添加了一个选项来传递关键字,这些关键字将被传递给read_csv,我还漏掉了一个 not 与我的编辑;0
how to change this function to output excel file instead of .csv? I tried but the error i keep getting is: UnicodeDecodeError: 'charmap' codec can't decode byte 0x8d in position 17: character maps to <undefined> , when applying it to read excel file.
@Jessica,设置 encoding="utf8" 在公开电话中。
我试过'encoding='latin-1'没有错误信息,但也没有输出,脚本似乎永远在运行。 @Padraic Cunningham
@Jessica,你需要指定正确的编码,否则你可能会产生垃圾,你知道数据被编码的实际编码吗?另外,就永远运行而言,如果你的文件非常大,可能需要相当长的时间来解析,while循环不可能永远不结束,因为它在匹配或EOF时停止。
The AG
The AG
发布于 2021-06-25
0 人赞同

另一个实现动态跳线的简单方法是这样的,这对我来说很有效。

# 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]