Как я могу найти только файлы, содержащие дату последнего дня месяца, используя Python?

#python #pandas #loops #date #re

Вопрос:

У меня есть папка с сотнями файлов .xlsx, которые являются ежедневными данными многолетней давности.

Шаблон имени файла — ‘ABC DEF 20150501.xlsx’

Как я могу выбрать файлы за последний день каждого месяца за все эти годы.

К сожалению, я понятия не имею, как это сделать.

 import pandas as pd
import re

files = [f for f in os.listdir(path) if re.match(r'ABC DEF [0-9] .xlsx', f)]
df = pd.DataFrame(files)
df.columns = ['file_name']
df['port_date'] = df['file_name'].apply(lambda x : x.split(' ')[3].split('.')[0])
 

У меня есть только дата в одной колонке, и у меня закончилась идея!

Любая помощь будет оценена по достоинству.

Комментарии:

1. У вас могут быть два файла с разными «ABC-настройками», но с одной и той же датой?

2. нет, часть «ABC DEF» исправлена. отличается только ДАТА.

3. последнее значение, если месяц означает последний календарный день, подобный 31.dec или последний существующий день для декабря месяца для каждого года, аналогично для каждого названия месяца.

4. в основном последняя дата, которая существует в каждом месяце

Ответ №1:

В следующем коде используется функция, которая добавляет день к дате, а затем сравнивает месяц новой даты с месяцем исходной даты, если они отличаются, исходная дата является последним днем месяца.

 import pandas as pd
from datetime import datetime, timedelta

def last_day(to_date):
    delta = timedelta(days=1)
    next_day = to_date   delta
    if to_date.month != next_day.month:
        return True
    return False

# read dummy filename data
df = pd.read_csv('test.csv')

df['port_date'] = pd.to_datetime(df['file_name'].str[8:16])

df['lastday'] = df['port_date'].apply(lambda dt: last_day(dt))
 

Ответ №2:

Если нужна последняя строка для каждого месяца и года, извлеките даты и время, сортировку и группировку по годам и месяцам с помощью GroupBy.last :

 df = pd.DataFrame({'file_name':['ABC DEF 20150501.xlsx',
                                'ABC DEF 20150701.xlsx',
                                'ABC DEF 20150711.xlsx']})

print (df)
               file_name
0  ABC DEF 20150501.xlsx
1  ABC DEF 20150701.xlsx
2  ABC DEF 20150711.xlsx

df['port_date'] = pd.to_datetime(df['file_name'].str.extract('(d ).', expand=False))
df = df.sort_values('port_date')

df = (df.groupby([df['port_date'].dt.year, df['port_date'].dt.month])
        .last()
        .reset_index(drop=True))
print (df)
               file_name  port_date
0  ABC DEF 20150501.xlsx 2015-05-01
1  ABC DEF 20150711.xlsx 2015-07-11
 

Ответ №3:

Объявите функцию:

 def contains_date_of_last_day(name):
  last_days = [
    '0131',
    '0228',
    '0331',
    '0430',
    '0531',
    '0630',
    '0731',
    '0831',
    '0930',
    '1031',
    '1130',
    '1231',
    ]
  for i in last_days:
    if i in name: return True
      return False
    
 

Проверьте, содержит ли дата последнего дня, используя функцию:

 files = [f for f in os.listdir(path) if contains_date_of_last_day(f)]
 

Комментарии:

1. У меня есть синтаксическая ошибка: внешняя функция «возврат»

2. должно сработать сейчас