【问题标题】:Looping CSV Concat in Python Pandas在 Python Pandas 中循环 CSV Concat
【发布时间】:2015-09-04 04:09:12
【问题描述】:

我有多个文件夹,每个文件夹都包含 csv。我正在尝试连接每个子目录中的 csv,然后将其导出。最后,我将拥有与文件夹相同数量的输出。最后我想要 Folder1.csv、Folder2.csv、...Folder99.csv 等。这就是

import os
from glob import glob
import pandas as pd
import numpy as np



rootDir = 'D:/Data'
OutDirectory = 'D:/OutPut'
os.chdir(rootDir)

# The directory has folders as follows
# D:/Data/Folder1
# D:/Data/Folder2
# D:/Data/Folder3
# ....
# .....
# D:/Data/Folder99

# Each folders (Folder1, Folder2,..etc.) has many csvs.

frame = pd.DataFrame()
list_ = []
for (dirname, dirs, files) in os.walk(rootDir):
for filename in files:
    if filename.endswith('.csv'):
        df = pd.read_csv(filename,index_col=None, na_values=['-999'], delim_whitespace= True, header = 0,  skiprows = 2)
        OutFile = '%s.csv' % OutputFname
        list_.append(df)
        frame = pd.concat(list_)

        df.to_csv(OutDirectory+OutFile, sep = ',', header= True)

我收到以下错误:

IOError: File file200150101.csv does not exist

【问题讨论】:

    标签: python-2.7 csv pandas


    【解决方案1】:

    您需要连接 dirname 和 filename 以获得文件的完整路径。像这样改变这一行:

    df = pd.read_csv(os.path.join(dirname, filename) ,index_col=None, na_values=['-999'], delim_whitespace= True, header = 0, skiprows = 2)
    

    编辑:
    我不知道 pandas 是如何工作的,因为我从未使用过它。但我认为您的问题是,您在仅循环文件的内部循环中定义了您想要对 CSV 执行的所有操作(至少缩进看起来是这样 - 但这也可能是您粘贴时发生的格式问题你的代码在这里)。

    我重写了你的代码并修复了一些我认为可能是问题的地方:

    • 首先,我以大字母开头重命名了变量,因为,
      对我来说,使用大开头字母的 var 总是看起来很奇怪。
    • 我将您的列表变量移到了外循环,因为它应该是
      每次输入新目录时重置,因为您希望所有 CSV 每个文件夹合并。
    • 最后,我修复了缩进。在python缩进告诉 编译器哪些命令位于内部或外部循环中。

    我的代码现在看起来像这样。您可能需要更改一些内容,因为我现在无法对其进行测试:

    import os
    from glob import glob
    import pandas as pd
    import numpy as np
    
    
    
    rootDir = 'D:/Data'
    outDir = 'D:/OutPut'
    os.chdir(rootDir)
    dirs = os.listdir(rootDir)
    
    frame = pd.DataFrame()
    for dirname in dirs: 
      # the outer loop loops over directories! the actual directory is stored in dirname
      list = [] # collect csv data for every directory, not in general
      files = glob('%s/*.csv' % (dirname))
      for filename in files:
        # the inner loop loops over the files in the 'dirname' folder
        df = pd.read_csv(filename,index_col=None, na_values=['-999'], delim_whitespace= True, header = 0,  skiprows = 2)
        # all csv data should be in 'list' now
        outFile = '%s.csv' % dirname # define the name for output csv
        list.append(df) # do that for every file
        # at this point, all files in the actual directory were processed
    
    frame = pd.concat(list_) # and then merge CSVs
    # ...actually not sure how pd.concat works, but i guess it does merge the data
    frame.to_csv(os.path.join(outDir, outFile), sep = ',', header= True) # save the data
    

    【讨论】:

    • 当我手动执行文件夹的代码时,它会在相当短的时间内完成,现在循环需要相当长的时间。它还在每个 csv 中逐行添加输出。我没有在上面的代码中进行计算,但涉及到一些重采样。
    • 您是否尝试使用print (os.path.join(dirname, filename)) 列出循环处理的文件以检查循环是否真正到达它们?如果是这样,那可能是 panda 的问题。
    • 是的,它正在吐出输出,但它几乎没有爬行,几个小时后我只生成了三个输出
    • 我在我的电脑上测试了一个treewalk,使用的代码基本相同,但减去了熊猫的东西(从未与熊猫合作过),它对我来说完美无缺。也许您的性能问题是由循环中的熊猫代码引起的。也许尝试先收集 csv 记录,然后在循环完成后将它们连接起来。我不认识熊猫,但似乎frame = pd.concat(_list) 一遍又一遍地遍历您的 csv 记录集合,因为它变得越来越大。在你的循环之后尝试这样做。
    • 我重写了您的代码并编辑了我认为应该(接近)正确的代码;)
    猜你喜欢
    • 2022-08-17
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多