【问题标题】:How to add the filename to the last line read in of every file?如何将文件名添加到每个文件读入的最后一行?
【发布时间】:2019-03-07 22:03:08
【问题描述】:

我有一组逐行读取的文件。我希望每个文件的最后一行都有文件名。这是完成文件部分读取的代码,但我不知道如何显示文件名:

import glob

a = []

def convert_txt_to_dataframe(path):
    for files in glob.glob(path + "./*manual.txt"):
        for x in open(files):
            a.append(x)

这样就完成了逐行导入所有文本文件,所以现在我希望每个文件的最后一行都有一个随附的文件名

我希望它看起来像:

     Hello                                      Goodbye
0    Thank you for being a loyal customer.      MyDocuments/TextFile1
1    Thank you for being a horrible customer.   MyDocuments/TextFile1
2     Thank you for being a nice customer.      MyDocuments/TextFile3

【问题讨论】:

  • 您能否举例说明您想要实现的目标?
  • 所以a[-1] += filesfor x in .. 循环之后?
  • @Martihn Pieters,你能写出完整的代码,以便我完全理解你在说什么吗?
  • @Srini,我添加了我想看到的输出
  • 很抱歉,我仍然无法理解所需的输出。什么是你好和再见? 0,1,2 代表 3 个不同文件的最后几行吗?

标签: python python-3.x dataframe import glob


【解决方案1】:

所以我假设您正在获取文件列表,并且您提到的那些列 [0,1,2] 指的是列表中每个文件的最后一行。考虑到这一点,我会尝试一种更简单的方法而不是数据框。即使您出于其他原因必须使用数据框,也许您可​​以在最后一步转换为文本并尝试以下操作:

Example File ("ExampleText2"):
I love coffee
I love creamer
I love coffee and creamer
I have a rash..

代码:

last = []
with open('exampleText2.txt', 'r') as f:
    last = f.readlines()[-1] + " other FileName"

输出:

最后 '我有皮疹.. 其他文件名'

readlines() 将返回文件中所有行的列表,因此您可以尝试调用 -1 来提取最后一行,然后添加到它。

【讨论】:

    【解决方案2】:

    我假设行数大于或等于文件数。

    import glob
    
    words = ['Thank you for being a loyal customer.',
             'Thank you for being a horrible customer.',   
             'Thank you for being a nice customer.']    
    
    def convert(path):
        a = []
        z = 0
        for files in glob.glob(path + "/*.txt"):
            temp = [words[z],files]
            a.append(temp)
            z += 1
        print (a)    
    
    convert(your_path)
    

    【讨论】:

      【解决方案3】:

      这个问题定义不明确,但假设 OP 想要 DataFrame 示例中显示的结果(即,不仅最后一行以某种方式用文件名装饰,而且所有行都是),这是实现这一目标的一种方法。对于这个例子,我们只有两个文件:file1.txt 包含两行:'a' 和 'b',file2.txt 包含一行:'c'。

      我们编写了一个文件阅读器,它返回一个列表列表:每个子列表包含文件名和一行。

      import glob
      
      def get_file(filename):
          with open(filename) as f:
              return [[filename, line.rstrip('\n')] for line in f]
      

      试试看:

      m = map(get_file, glob.glob('file*.txt'))
      list(m)
      
      Out[]:
      [[['file2.txt', 'c']], [['file1.txt', 'a'], ['file1.txt', 'b']]]
      

      让我们将这些列表展平以获得一个二维数组。此外,获得文件按字母顺序排序的结果可能会更好。

      def flatten(m):
          return [k for sublist in m for k in sublist]
      
      m = map(get_file, sorted(glob.glob('file*.txt')))
      flatten(m)
      
      Out[]:
      [['file1.txt', 'a'], ['file1.txt', 'b'], ['file2.txt', 'c']]
      

      现在,获得行号有时会有所帮助(例如,如果我们要将数据放入 DataFrame 并进行进一步的排序和分析)。我们的读者变成:

      def get_file(filename):
          with open(filename) as f:
              return [[filename, lineno, line.rstrip('\n')] for lineno, line in enumerate(f, start=1)]
      
      m = map(get_file, sorted(glob.glob('file*.txt')))
      out = pd.DataFrame(flatten(m), columns=['filename', 'lineno', 'line'])
      out
      
      Out[]:
          filename  lineno line
      0  file1.txt       1    a
      1  file1.txt       2    b
      2  file2.txt       1    c
      

      请注意,如果我们确实有大量文件,上面的 map 非常适合多线程读取:

      from concurrent.futures import ThreadPoolExecutor
      
      with ThreadPoolExecutor(max_workers=4) as pool:
          m = pool.map(get_file, sorted(glob.glob('file*.txt')))
          out = pd.DataFrame(flatten(m), columns=['filename', 'lineno', 'line'])
      out
      
      Out[]:
          filename  lineno line
      0  file1.txt       1    a
      1  file1.txt       2    b
      2  file2.txt       1    c
      

      【讨论】:

        猜你喜欢
        • 2021-01-22
        • 1970-01-01
        • 2015-02-27
        • 1970-01-01
        • 2013-11-19
        • 2023-02-10
        • 2019-06-23
        • 2022-07-01
        相关资源
        最近更新 更多