【问题标题】:How to delete few top rows and last row from a CSV file using python如何使用python从CSV文件中删除几行和最后一行
【发布时间】:2017-11-28 13:22:42
【问题描述】:

我有无法使用 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 附在here

我想要一个代码,可以在没有任何输入的情况下以某种方式删除这些行。

注意:没有关于 CSV 中最后一行的信息,但它是这样的:

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

【问题讨论】:

  • “直到标题行”是否意味着您也想删除标题行,或者只删除标题行之前的行?标题行或前一行或后一行的特征是什么,可用于将它们与文件中的任何其他行区分开来?
  • 对不起,这是一个错误,我已经编辑了问题@rd_nielsen

标签: python excel csv pandas numpy


【解决方案1】:
import pandas as pd
df = pd.read_csv('file_name.csv', skiprows=27)
df.drop(df.index[5421327]) #5421327 = 5421344-27

您可以使用 pandas 和 read_csv 模块来完成。 Skiprows 定义要在文件开头跳过的行号(0-indexed)或要跳过的行数(int)。 最后用 5421344 索引放置 col。

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

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

【讨论】:

    【解决方案2】:

    这可以使用 Python 的 csv 库来帮助解析文件,并使用 itertools dropwhiletakewhile 函数来挑选你想要的行:

    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 文件的每一行,直到找到第一列包含 Report Fields 的行。然后它会跳过这一行。现在它将所有剩余的行写入输出 CSV 文件,直到第一列条目包含单词 Grand Total,然后停止。

    【讨论】:

    • 它给了我 错误:迭代器应该返回字符串,而不是字节(您是否以文本模式打开文件?) 解决此问题的错误我将 rb 和 wb 替换为 rt 和wt 分别运行,但输出文件除了标题之外什么都没有。 @MartinEvans
    • 我已经更新了脚本,它是为 Python 2.x 设计的。错误消息暗示您使用的是 Python 3.x
    • 我每次都必须创建一个新文件,因为它没有创建文件吗?另外,现在它给出了 UnsupportedOperation: not writable 错误,我认为这是因为文件可能以只读状态打开。忍受我,因为我是一个相当新手,并迫使我通过这一切。 @MartinEvans
    • 它读取一个文件,然后创建另一个。确保在运行脚本时没有在另一个应用程序中打开 output.csv。如果您尝试使两个文件具有相同的名称,它将无法正常工作。
    • 它运行但返回一个空文件,只有标题行@MartinEvans
    【解决方案3】:

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

    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)
    

    【讨论】:

    • 我想创建一个新文件作为 outfile。另外,当您说 时,我是否必须将标题行保存为列表?
    • 如何处理该行取决于您需要如何检查它以确定它是否是标题行。我认为您很可能可以使用子字符串搜索或正则表达式来匹配列标题中的某些已知值。
    【解决方案4】:

    我首先将整个文件作为字符串读取,然后将其拆分为您尝试读取的数据帧'Report Fields' 的指示器。然后,您可以通过在换行符处拆分并索引列表以包含除最后一行之外的所有行来消除最后一行 [:-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]))
    

    【讨论】:

    • 我收到错误 TypeError: expected str, bytes or os.PathLike object, not _io.TextIOWrapper @piRSquared
    • 错误在哪里。我写的东西对我有用。
    • 它现在正在运行,但与其他文件一起使用时会删除所有内容@piRSquared
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多