首页 > 解决方案 > 使用从不同行开始的 Pandas 处理多个 csv

问题描述

我目前正在使用这样的 for 循环处理 PD 数据帧中的多个 CSV 文件:

for csvfile in all_filenames:
    with open(csvfile, 'r') as csvopen:
        content = csvopen.read() 
        csvopen.seek(0)
        dialect = csv.Sniffer().sniff(csvopen.readline(), [',',';','\t'])
    combined_csv = pd.read_csv(csvfile, sep=dialect.delimiter)
    appended_data.append(combined_csv)
    
appended_data = pd.concat(appended_data)

问题是 CSV 文件有时包含空白行,并且可能另外包含 1 行冗余信息,从而导致 3 个变体。列名也不同,我使用 dict 重新映射(参见下面的代码)。

例如:

CSV 1
Line 1: No, Company, Contact Person name
Line 2: 1, EG, Tim
CSV 2
Line 1:
Line 2:
Line 3: No, Company, Contact Person
Line 4: 2, Given, Sarah
CSV 3
Line 1:
Line 2:
Line 3: This file contains information about..
Line 4: Number, Company name, Contact Person
Line 5: 3, Example, Johnny

有什么方法可以动态处理这些文件,而不必事先手动删除这些行?如果适用,我想忽略文件中的空白行和描述行(例如 CSV 3,第 3 行),因此嗅探器不会使用它们来确定分隔符并且不包含在数据框中。

另一个问题是列名的拼写不同。我目前使用 dict 将这些列映射到一个值,但我只能在文件被处理成数据框后处理它。

general_dict = {'Number': ['No'],
                'Company': ['Company name']}

    col_list = combined_csv.columns.to_list()
      
    for col in col_list:
        for key, val in general_dict.items():
            if col in val:
                rename_dict[col] = key
            
                break

标签: pythonpandascsv

解决方案


在进一步检查有问题的 CSV 文件后,感谢@tripleee 的建议,我在使用 latin1 编码打开 csv 时发现了一个 \n\n 字符。

通过添加以下代码行,我能够一次性处理所有文件。

content = re.sub('\ufeffTextbox7[\n]','',content)
content = re.sub('.*[\n]{2,}','',content)

不是最干净的解决方案,但适用于我的情况!

for csvfile in all_filenames:
    try:
        with open(csvfile, 'r') as csvopen:
            content = csvopen.read() 
            csvopen.seek(0)
            dialect = csv.Sniffer().sniff(csvopen.readline(), [',',';','\t'])
    except:
        with open(csvfile, 'r', encoding='utf-8') as csvopen:
            content = csvopen.read() 
            content = re.sub('\ufeffTextbox7[\n]','',content)
            content = re.sub('.*[\n]{2,}','',content)
            csvopen.seek(0)
            dialect = csv.Sniffer().sniff(csvopen.read(10000), [',',';','\t'])
    combined_csv = pd.read_csv(StringIO(content), sep=dialect.delimiter, engine='python', quotechar='"', encoding='utf8')

双换行符的一个 re.sub 可以工作,但如果文件中没有出现 \uffef,我宁愿将它们分开。


推荐阅读