2017-09-22 10 views
0

以下のコードは必要なときに機能しますが、もっと良い方法が必要だと感じています。私はそれの中に毎日(ish)ファイルを含むフォルダを持っています。それらはすべて同じ接頭辞とファイル名として送信された日付を持ちます。特定の日には、ファイルはまったく送信されませんでした。私の仕事は毎月最後のファイルを読むことです(ほとんどの時間は最後の日ですが、4月の最後のファイルは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]) 

私は、これは私がハンマー(パンダ)を持っているので、すべてが(私はデータフレームにすべてを回す)爪のように見える、そうであると信じています。私はまた、数年後にそれらを使用しないで理解をリストするのに慣れようとしています。

答えて

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

ので、ファイル名は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多くで働いていません。だから、ネイティブスタイルで1ヶ月の最大日付に一致するファイルを取得しました。

+0

クール、ええ、私はパンダ以外のソリューションを見たいと思っていました。私もこれを試してみます。 – trench

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]) 
関連する問題