递归地将子文件夹中的文件读取到列表中,并将每个子文件夹的文件合并为每个子文件夹的一个 csv

iNo*_*oob 4 python csv pandas

我正在尝试解决如何使用pandas递归导航文件夹子文件夹,获取子文件夹中的每个文件并将其合并为每个子文件夹的一个 CSV 文件。

所以我在类似于下面的结构中有多个文件。我想获取每个子文件夹并将其各自的 CSV 合并到每个子文件夹中的一个文件中。请参阅第二个图示文件夹树。我pandas以前没有使用过,但我认为我在正确的轨道上,我正在努力为每个子文件夹制定逻辑。请参考下面我当前的代码。

*注意,每个 CSV 文件的列结构都相同。

合并前

Folder
      Sub-Folder1
               File1.csv
               File2.csv
               File3.csv
               File4.csv
      Sub-Folder2
               File1.csv
               File2.csv
      Sub-Folder3
               File1.csv
               File2.csv
Run Code Online (Sandbox Code Playgroud)

合并后

Folder
      Sub-Folder1
               Final.csv
      Sub-Folder2
               Final.csv
      Sub-Folder3
               Final.csv
Run Code Online (Sandbox Code Playgroud)

当前代码

import pandas as pd

working_dir = "/dir/"

for root, dirs, files in os.walk(working_dir):
    file_list = []
    for filename in files:
        file_list.append(root + "/" + filename) 
    df_list = [pd.read_table(file) for file in file_list]
    final_df = pd.concat(df_list) 
    final_df.to_csv(root + "/" + "Final.csv")
Run Code Online (Sandbox Code Playgroud)

目前收到以下错误

ValueError: All objects passed were None 在线的 big_df = pd.concat(df_list)

进行 Anand S Kumar 建议的更正后的输出数据

csv 被格式化为一个不需要或不需要的新列,并且数据集被完整地放入第二列。

    title1,title2,title3,title4
0   data1,data2,data3,data4
1   data1,data2,data3,data4
2   data1,data2,data3,data4
0   data1,data2,data3,data4
1   data1,data2,data3,data4
2   data1,data2,data3,data4
3   data1,data2,data3,data4
Run Code Online (Sandbox Code Playgroud)

按照 Anand S Kumar 的建议添加的数据集

title1,title2,title3,title4
13,[Group] data1,[Group] data2,data3
11,[Group] data1,[Group] data2,data3
2,[Group] data1,[Group] data2,data3
1,[Group] data1,[Group] data2,data3
Run Code Online (Sandbox Code Playgroud)

Ana*_*mar 5

问题很可能是在主目录中 - Folder(或/dir根据您的代码),您没有任何文件,因此file_list是空的,因此df_list也是空的。因此,当您将空列表传递给 时pd.concat(),您会收到该错误。例子 -

In [5]: pd.concat([])
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython> in <module>()
----> 1 pd.concat([])

/path/to/merge.py in concat(objs, axis, join, join_axes, ignore_index, keys, levels, names, verify_integrity, copy)
    752                        keys=keys, levels=levels, names=names,
    753                        verify_integrity=verify_integrity,
--> 754                        copy=copy)
    755     return op.get_result()
    756

/path/to/merge.py in __init__(self, objs, axis, join, join_axes, keys, levels, names, ignore_index, verify_integrity, copy)
    797
    798         if len(objs) == 0:
--> 799             raise ValueError('All objects passed were None')
    800
    801         # consolidate data & figure out what our result ndim is going to be

ValueError: All objects passed were None
Run Code Online (Sandbox Code Playgroud)

我建议你应该检查你正在阅读的文件确实是文件和他们最终用.csv,而且df_list不为空,当你将它传递到pd.concat()。此外,我建议您使用os.path.join()而不是连接字符串来创建路径。例子 -

import pandas as pd
import os.path
import os

working_dir = "/dir/"

for root, dirs, files in os.walk(working_dir):
    file_list = []
    for filename in files:
        if filename.endswith('.csv'):
            file_list.append(os.path.join(root, filename)) 
    df_list = [pd.read_table(file) for file in file_list]
    if df_list:
        final_df = pd.concat(df_list) 
        final_df.to_csv(os.path.join(root, "Final.csv"))
Run Code Online (Sandbox Code Playgroud)

编辑:

正如你所说 -

此外,输出还添加了另一列,它看起来是一个 id 列。

进来的新列很可能是 DataFrame 的索引。

这样做时DataFrame.to_csv(),如果您不想将 DataFrame 的索引写入 csv ,则应指定index关键字参数 asFalse以便索引不会写入 csv。例子 -

final_df.to_csv(os.path.join(root, "Final.csv"), index=False)
Run Code Online (Sandbox Code Playgroud)