【问题标题】:Delete or remove headers from text files being read in从正在读入的文本文件中删除或删除标题
【发布时间】:2019-03-28 20:04:20
【问题描述】:

我正在尝试删除或删除我正在使用 pandas 读取的数据标题。一个文件有标题,另一个没有,但我希望能够检查标题然后将其删除。

到目前为止,我已经尝试在 read_csv 函数中使用 header=None

from pathlib import Path
import pandas as pd

def _reader(fname):
    return pd.read_csv(fname, sep="\t", header=None)

folder = Path("C:\\Me\\Project1")
data = pd.concat([
    _reader(txt)
    for txt in folder.glob("*.txt")
])

我收到以下错误: TypeError: 必须是 str,而不是 int

我的两个文件如下所示:

文件1.txt

ISIN    AVL_QTY
BAD 90000
AAB 8550000
BAD 173688
BAD 360000
BAD 90000
BAD 810000
BAD 900000
BAD 900000

文件2.txt

TEST  543
HELLO 555
STOCK 900
CODE  785

【问题讨论】:

  • 使用 header=0 看看是否有效
  • 不走运,KeyError 说:0
  • 有一个 skiprows 参数可以传递给 reqd_csv。

标签: python pandas


【解决方案1】:

首先,您需要检查第一行是否为标题。例如。您可以检查第一行的任何条目是否以数字开头,因为这对于列标题来说不是典型的。 事实上,在不了解您的数千个文件的情况下,正确的标头检测方法只是猜测 - 但这并不是您代码中的重点。

要使用标头检测,您应该使用普通循环而不是列表推导,这样您就可以在每次迭代中: 1. 检查标头 2. 读取文件并将数据附加到数据帧:

df = pd.DataFrame()

for f in folder.glob("*.txt"):
    with open(f) as fin:
        chk_lst = next(fin).split()
    is_h = not any(v[0].isdecimal() for v in chk_lst)
    df = pd.concat([df, pd.read_csv(f, sep='\s+', header=(None, 0)[is_h])], axis=1)

# ISIN  AVL_QTY      0        1
# 0  BAD    90000   TEST  543.775                             
# 1  AAB  8550000  HELLO  555.000                           
# 2  BAD   173688  STOCK  900.000                         
# 3  BAD   360000   CODE  785.000                         
# 4  BAD    90000    NaN      NaN                        
# 5  BAD   810000    NaN      NaN                         
# 6  BAD   900000    NaN      NaN                         
# 7  BAD   900000    NaN      NaN                

编辑:
对于连接行明智,您可以使用

    df = pd.concat([df, pd.read_csv(f, sep='\s+', header=None, skiprows=(0, 1)[is_h])], axis=0, ignore_index=True)

#        0        1
# 0    BAD    90000                                     
# 1    AAB  8550000                                      
# 2    BAD   173688                                         
# 3    BAD   360000                                      
# 4    BAD    90000                                        
# 5    BAD   810000                                        
# 6    BAD   900000                                    
# 7    BAD   900000                                    
# 8   TEST      543                                       
# 9  HELLO      555                                      
# 10 STOCK      900                                       
# 11  CODE      785                              

【讨论】:

  • 感谢分享。如何在下一行而不是并排打印最后两列?
  • 一般通过设置axis=0来完成。但是,在这种情况下,我会将 header 修复为 None 并添加 skiprows 以依赖于 is_h
  • 更改为编辑版本会呈现此错误:TypeError:initial_value 必须是 str 或 None,而不是 WindowsPath。删除的 StringIO 现在可以使用了
  • @ravecoder 对,抱歉,从我的测试脚本中复制/粘贴错误,我没有您的文件...已更正。
【解决方案2】:

File2.txt 没有标题,对吧?但是在_reader 中,您将header 设置为None。 将标题添加到 File2.txt 中,看看会发生什么。

【讨论】:

  • 这只是一个sn-p。实际上,我将读取数千个文件,因此我无法确定文件是否有标题。但就您而言,当我手动删除标题时,它工作正常
【解决方案3】:

有几种方法可以检查 csv 文件是否有标题

使用 csv 库

import csv
with open('example.csv', 'rb') as csvfile:
    sniffer = csv.Sniffer()
    has_header = sniffer.has_header(csvfile.read(2048))
    csvfile.seek(0)
    # ...

my source


或者如果你知道你的数据,检查第一行是否有数字

is_header = not any(cell.isdigit() for cell in csv_table[0])

my source


或者使用 pandas 本身,如果你知道标题 可能 被称为什么

df = (pd.read_csv(filename, header=None, names=cols)
      [lambda x: np.ones(len(x)).astype(bool)
                 if (x.iloc[0] != cols).all()
                 else np.concatenate([[False], np.ones(len(x)-1).astype(bool)])]
    )

my source


当然,如果你想先用命令行预处理文件,它可能会更快......

【讨论】:

    猜你喜欢
    • 2013-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    相关资源
    最近更新 更多