首页 > 解决方案 > 如何组合名称包含来自两个字典的单词的 CSV 文件?

问题描述

我有一个包含多个文件的文件夹:

files = ['apple29c9_michigan_1995.csv',
         'apple30c7_rome_1995.csv',
         'apple67c5_melba_1995.csv',
         'apple12c2_rome_2010.csv',
         'mango76c6_southern_blush_1995.csv',
         'mango76c6_southern_1995.csv',
         'mango76c6_blush_1995.csv',
         'mango65c2_southern_blush_2020.csv',
         'mango34c4_keitt_1995.csv',
         'mango22c5_kent_1995.csv',
         'mango76c6_southern_blush_sweet_1995.csv',
         'mango76c6_sweet_southern_blush_1995.csv']

我有两个字典和一个变量(制造年份):

d1 = {'Filename': ['apple','mango']}
d2 = {'Filetype': ['rome', 'melba', 'southern_blush', 'kent']}
yr = 1995

我怎样才能:

  1. 从文件夹中选择所有文件,其中文件名包含:

    • 要么Filename'apple'要么'mango'
    • AND 任何Filetype, 'rome', 'melba', 'southern_blush', 或'kent'
      • 必须完全匹配(例如sweet_southern_blush不等于southern_blush
    • yr, 如 1995
  2. 将属于每个文件名的文件附加在一起。

    • 苹果的一个文件,该文件将具有apple30c7_rome_1995.csvapple67c5_melba_1995.csv附加
    • 同样,芒果文件的一个文件。

输出应该是:

apple30c7_rome_1995.csv
apple67c5_melba_1995.csv >> Appended into one file


mango76c6_southern_blush_1995.csv
mango22c5_kent_1995.csv >> Appeneded into one file

标签: python

解决方案


  1. 使用pathlib模块获取所有文件

    • 该模块提供了表示文件系统路径的类,这些类具有适用于不同操作系统的语义。
    • 用于.glob查找具有指定模式的文件
    • 用于.stem仅提取文件名以用于条件
      • WindowsPath('E:/PythonProjects/stack_overflow/apple30c7_rome_1995.csv').stemapple30c7_rome_1995,例如。
  2. 预先创建术语的组合 , combos

  3. 遍历文件,并在通过条件时将文件添加到dict, files_to_combine

    • f_name被分成一个列表_
      • fn = f_name[0]始终是Filename组件,因此它必须包含n,因此n in fn
      • y = f_name[-1]总是年份,所以它必须等于yr,因此yr == y
      • ft = f_name[1:-1]Filetype组件,因此它必须与中的任何值完全匹配t
    • 对于发电机any(v == ft for v in t)
      • for-loop,t['rome', 'melba', 'southern_blush', 'kent']v遍历 的每个值t
      • v == ft创建一个布尔值TrueFalse如果vft或不是。
      • anyTrue如果生成器中的任何布尔值是 ,则返回True
      • 要在完全str匹配或包含str、 选择==或之间进行切换in
  4. 使用pandas.read_csv,pandas.concatpandas.DataFrame.to_csv读取、组合和写入 csv 文件。

    • 对于此示例,创建了两个文件,apple_1995.csv并且mango_1995.csv.
import pandas as pd
from pathlib import Path
from collections import defaultdict as dd


yr = str(yr)  # convert year to a str
combos = [[n] + [d2['Filetype']] for n in d1['Filename']]  # list of unique combination

# find files in specified path
files = Path('c:/path_to_files').glob('*.csv')

# group matching combos in a dict
files_to_combine = dd(list)
for file in files:
    f_name = file.stem.split('_')  # get the file name and split it into a list
    y = f_name[-1]  # year
    fn = f_name[0]  # filename string
    ft = '_'.join(f_name[1:-1])  # filetype string
    for (n, t) in combos:  # iterate through each list in combos
        if (n in fn) and (yr == y) and any(v == ft for v in t):  # check the conditionals
            
            files_to_combine[f'{n}_{yr}'].append(file)  # add to the appropriate dict key
            
# combine csv groups into one group
for k, v in files_to_combine.items():
    df = pd.concat([pd.read_csv(file) for file in v])
    df.to_csv(f'{k}.csv', index=False)

combos

[['apple', ['rome', 'melba', 'southern_blush', 'kent']],
 ['mango', ['rome', 'melba', 'southern_blush', 'kent']]]

files_to_combine

defaultdict(<class 'list'>,
            {'apple_1995': [WindowsPath('apple30c7_rome_1995.csv'),
                            WindowsPath('apple67c5_melba_1995.csv')],
             'mango_1995': [WindowsPath('mango76c6_southern_blush_1995.csv'),
                            WindowsPath('mango22c5_kent_1995.csv')]})

推荐阅读