在文件夹中查找每个日历月的最新文件

时间:2017-09-22 12:48:04

标签: python pandas

下面的代码可以正常运行,但我觉得必须有更好的方法。我有一个包含每日(ish)文件的文件夹。所有这些都具有相同的前缀和它们作为文件名发送的日期。在某些日子里,根本没有发送文件。我的任务是阅读每个月的最后一个文件(大部分时间是最后一天,但是四月的最后一个文件是28日,7月是29日等)。

这是使用pathlib模块,我想继续使用它。

files = sorted(ROOT.glob('**/*.csv*'))
file_dates = [Path(file.stem).stem.replace('prefix_', '').split('_') for file in files] #replace everything but a list of the date elements
dates = [pd.to_datetime(date[0] + '-' + date[1] + '-' + date[2]) for date in file_dates] #construct the proper date format
x = pd.DataFrame(dates)
x['month'] = x[0].dt.strftime('%Y-%m') + '-01'
max_value = x.groupby(['month'])[0].max().reset_index()
max_value[0] = max_value[0].dt.strftime('%Y_%m_%d')
monthly_files = [str(ROOT / 'prefix_') + date + '.csv.xz' for date in max_value[0].values]

df = pd.concat([pd.read_csv(file, usecols=columns, sep='\t', compression='xz', dtype=object) for file in monthly_files])

我相信这是一个案例,因为我有一把锤子(熊猫),所有东西看起来像钉子(我把所有东西都变成了数据帧)。我也试图在几年不使用它们之后习惯列出理解。

3 个答案:

答案 0 :(得分:1)

可能会更好,但这是我的尝试:

files = sorted(ROOT.glob('**/*.csv*'))
file_dates = [Path(file.stem).stem.replace('prefix_', '').split('_') for file in files] #replace everything but a list of the date elements

df = pd.DataFrame(file_dates, columns=['y', 'm', 'd'], dtype='int')
monthly = [str(yy)+'-'+str(mm)+'-'+str(df.loc[(df['y'] == yy) & (df['m'] == mm), 'd'].max()) for yy in df.y.unique() for mm in df.m.unique()]

答案 1 :(得分:1)

因此文件名为prefix_<date>,日期格式为%Y-%m-%d

import os
from datetime import datetime as dt
from collections import defaultdict
from pathlib import Path

group_by_month = defaultdict(list)
files = []

# Assuming the folder is the data folder path itself.
for file in Path(folder).iterdir():
    if os.path.isfile(file) and file.startswith('prefix_'):
        # Convert the string date to a datetime object
        converted_dt = dt.strptime(str(file).split('prefix_')[1], 
                                   '%Y-%m-%d')

        # Group the dates by month
        group_by_month[converted_dt.month].append(converted_dt)

# Get the max of all the dates stored.
max_dates = {month: max(group_by_month[month]) 
             for month in group_by_month.keys()}

# Get the files that match the prefix and the max dates
for file in Path(folder).iterdir():
    for date in max_date.values():
        if ('prefix_' + dt.strftime(date, '%Y-%m-%d')) in str(file):
            files.append(file)

PS:我没有和pandas合作过很多次。因此,使用本机样式来获取与一个月的最大日期匹配的文件。

答案 2 :(得分:1)

据我所知,由于必须将当前元素与下一个元素进行比较,因此列表理解很难实现。

然而,有更简单的解决方案可以让你在没有大熊猫的情况下使用。

下面的示例只是循环一个包含文件日期的字符串列表,并在月份更改之前保留日期。由于您的列表已经排序,应该可以解决问题。我假设YYYY_MM_DD日期格式

files = sorted(ROOT.glob('**/*.csv*'))
file_dates = [Path(file.stem).stem.replace('prefix_', '') for file in files] 

#adding a dummy date because we're comparing to the next element
file_dates.append('0000_00_00')
result = []
for i, j in enumerate(file_dates[:-1]):
    if j[6:7] != file_dates[i+1][6:7]: 
        result.append(j)

monthly_files = [str(ROOT / 'prefix_') + date + '.csv.xz' for date in result]

df = pd.concat([pd.read_csv(file, usecols=columns, sep='\t', compression='xz', dtype=object) for file in monthly_files])