如何使用python从CSV文件中删除少数顶行和最后一行

如何使用python从CSV文件中删除少数顶行和最后一行,python,excel,csv,pandas,numpy,Python,Excel,Csv,Pandas,Numpy,我有无法使用Excel编辑的CSV文件。我想做一个动态代码来删除前几行(在标题行之前)和最后一行,而不输入行号。我现在使用的代码是: FIRST_ROW_NUM = 1 ROWS_TO_DELETE = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 5421344} with open('filename', 'r') as infile

我有无法使用Excel编辑的CSV文件。我想做一个动态代码来删除前几行(在标题行之前)和最后一行,而不输入行号。我现在使用的代码是:

FIRST_ROW_NUM = 1  
ROWS_TO_DELETE = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 5421344}
with open('filename', 'r') as infile,open('filename', 'w') as outfile:
     outfile.writelines(row for row_num, row in enumerate(infile, FIRST_ROW_NUM)
                    if row_num not in ROWS_TO_DELETE)
这个代码的问题是我必须手动输入行数才能删除它们

我遇到的另一个问题是,要删除的行数不是恒定的,并且文件之间会发生变化

示例CSV随附

我想要一个代码,它可以以某种方式删除这些行,而无需我方的任何输入

注意:CSV中没有关于最后一行的信息,但如下所示:

Grand Total: - -  - - - - - - - - - - - - - - -  - - - -  - -  - - - 

打开输入和输出文件,然后:

for line in infile:
    if <line matches header row>:
        break
outfile.write(line)
for line in infile:
    if <line matches grand total line>:
        break
    outfile.write(line)
对于内嵌中的行:
如果:
打破
输出文件。写入(行)
对于填充中的线:
如果:
打破
输出文件。写入(行)

我首先将整个文件作为字符串读取,并将其拆分为您试图读取的数据帧的指示符。然后,您可以使用
[:-1]

with open('infile.csv', 'r') as infile, open('outfile.csv', 'w') as outfile:
    txt = infile.read().split('Report Fields')[1]
    outfile.write('\n'.join(txt.split('\n')[1:-1]))
您可以使用pandas和read_csv模块来执行此操作。 Skiprows在文件开头定义要跳过的行号(0索引)或要跳过的行数(int)。 并在最后以5421344指数下降col

它用于静态值。 对于行或NaN之前的动态if行,您可以使用:

import pandas as pd
df = read_csv('file_name', skiprows=1)
df.dropna(axis=0, inplace=True)
df.drop(df.iloc[-1])

可以使用Python的库来帮助解析文件,并使用itertools和函数来选择所需的行:

import itertools    
import csv

with open('Test.csv', newline='') as f_input, open('output.csv', 'w', newline='') as f_output:
    csv_input = csv.reader(f_input)
    csv_output = csv.writer(f_output)

    # Skip over initial lines until the header row
    next(itertools.dropwhile(lambda x: x[0] != "Report Fields", csv_input))

    # Write rows until the total row is found
    csv_output.writerows(itertools.takewhile(lambda x: "Grand Total" not in x[0], csv_input))   

这将读取CSV文件的每一行,直到找到第一列包含
报告字段的行为止。然后它跳过这一行。现在,它将所有剩余的行写入输出CSV文件,直到第一列条目包含单词
Grand Total
,然后停止。

是否“直到标题行”意味着您也要删除标题行,还是只删除标题行之前的行?标题行、前一行或后一行的特征是什么,可以用来将它们与文件中的任何其他行区分开来?对不起,这是一个错误,我编辑了问题@rd_nielsenI想要创建一个新文件作为outfile。另外,当您说我必须将标题行保存为列表吗?您如何处理该行取决于您需要如何检查它以确定它是否为标题行。我认为最有可能的情况是,您可以使用子字符串搜索或正则表达式来匹配列标题中的某些已知值。我得到的错误类型是错误:应为str、bytes或os.PathLike对象,而不是_io.TextIOWrapper@pirSquared这里是错误。我写的东西对我来说很有用。它现在正在运行,但它在与其他文件一起使用时删除了所有内容@piRSquaredit给了我一个错误:迭代器应该返回字符串,而不是字节(你是在文本模式下打开文件的吗?)错误为了解决这个问题,我将rb和wb分别替换为rt和wt,它运行了,但输出的文件除了标题之外没有任何内容@MartinEvansI已经更新了脚本,它是为Python2.x设计的。错误消息暗示您正在使用Python 3.xDo,因为它没有创建文件,所以每次我都必须创建一个新文件?。另外,现在它给出了UnsupportedOperation:NotWritable错误,我认为这是因为文件可能以只读状态打开。请容忍我,因为我是一个相当的新手,我会强迫自己度过这一切@MartinEvansIt读取一个文件,然后创建另一个文件。确保在运行脚本时,没有在其他应用程序中打开
output.csv
。如果您尝试使两个文件具有相同的名称,则它将不起作用。它已运行,但返回的是一个仅包含标题行@MartinEvans的空文件
import itertools    
import csv

with open('Test.csv', newline='') as f_input, open('output.csv', 'w', newline='') as f_output:
    csv_input = csv.reader(f_input)
    csv_output = csv.writer(f_output)

    # Skip over initial lines until the header row
    next(itertools.dropwhile(lambda x: x[0] != "Report Fields", csv_input))

    # Write rows until the total row is found
    csv_output.writerows(itertools.takewhile(lambda x: "Grand Total" not in x[0], csv_input))