【问题标题】:Need help cropping a large text file to multiple small text files with a header需要帮助将大文本文件裁剪为带有标题的多个小文本文件
【发布时间】:2015-12-11 23:08:15
【问题描述】:

除了格式为 (number_of_lines, number_difference, "Sam") 的标题之外,我还需要裁剪一个包含超过 10000 行数字的大型文本文件

Number_difference 是第一个和最后一个数字之间的差。

例如,如果文件如下所示:

10
12
13.5
17
20

那么,标题应该是: 5 10 山姆

问题是标志在不多次写入标头时不起作用,并且大文件的标头会延续到第一个小文件。

每个文件的标题永远不会相同。

如何为每个文件添加更改的标题?

def TextCropper():


lines_per_file = 1000
smallfile = None
with open(inputFileName) as bigfile:
    for lineno, line in enumerate(bigfile):
            if lineno % lines_per_file == 0:
                if smallfile:
                    smallfile.close()
                    small_filename = 'small_file_{}.txt'.format(lineno + lines_per_file)
                    smallfile = open(small_filename, "w")
                    if (flags[counter] == False):
                        smallfile.write(lines_per_file)
                        flags[counter] = True
                    smallfile.write(line)
            elif smallfile:
                smallfile.close()

TextCropper()

【问题讨论】:

    标签: python csv text


    【解决方案1】:

    您一次读取和写入一行,效率低下。这样做,你也不知道最后一行是什么,所以你不能提前写你的标题。

    如果有的话,最多读 N 行。 islice() 将为您做到这一点。如果列表返回为空,则没有可读取的行,否则您可以继续将当前块写入文件。

    由于每行被读取为带有尾随换行符('\n')的数字,因此将其剥离,将第一个和最后一个数字转换为浮点数并计算差值。通过连接列表的元素,将实际数字写入文件很简单。

    要使函数可重用,请将可能更改的变量作为参数包含在内。这样,您可以命名任何大文件、任何输出小文件和任意数量的行,而无需更改硬编码值。

    from itertools import islice
    
    def number_difference(iterable):
        return float(iterable[-1].strip('\n')) - float(iterable[0].strip('\n'))
    
    def file_crop(big_fname, chunk_fname, no_lines):
        with open(big_fname, 'r') as big_file:
            ifile = 0
            while True:
                data = list(islice(big_file, no_lines))
                if not data:
                    break
                with open('{}_{}.txt'.format(chunk_fname, ifile), 'w') as small_file:
                    small_file.write('{} {} Sam\n'.format(len(data), number_difference(data)))
                    small_file.write(''.join(data))
                ifile += 1
    

    【讨论】:

    • 我不确定您是如何使用该程序的,但它应该适用于您在问题中描述的文件,即每行仅包含一个数字的文本。如果您将'45' 作为float() 的输入,它将输出为45.0。但是如果你输入45fdr,它就会失败。鉴于您遇到的错误,您似乎试图将该程序用于具有由同一程序创建的标题的文件。
    • 原文件中有一个header。什么是删除非手动标题的聪明方法?其中一些数字是 45.12352,并非所有数字都是整数
    • 如果你总是保证在原始文件中有一个你想忽略的标题,那么只要你打开文件,就在ifile = 0之前做big_file.readline()。这将丢弃第一行,因为您不会将其保存到任何变量中,并且会移动光标以准备从第二行开始读取。
    • 谢谢!我将审查您的代码并学习如何制作更通用的程序。
    • 我将如何修改代码以便我从其余数字中减去第一个数字作为整数?假设第一个位置是 12345.678,下一个位置是 12346.978。我会将第一个位置更改为 int(round(float(iterable[0].strip('\n')))) 并从两个位置中减去它。新线将分别为 0.6780 和 1.9780。我想使用 islice 而不使用另一个乏味的 for 循环。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-25
    相关资源
    最近更新 更多