Как найти последнюю отметку времени за каждый день из списка меток времени и даты за несколько дней? - PullRequest
1 голос
/ 13 мая 2019

Прошу прощения, если это очень простой вопрос. Большое спасибо за ваше время, чтобы пройти через это.

У меня есть данные CSV в следующем формате.

2019-05-10 13:00:00 some_data,some_more_data,...
2019-05-10 16:20:10 some_data,some_more_data,...
2019-05-10 19:21:10 some_data,some_more_data,...

2019-05-11 01:10:10 some_data,some_more_data,...
2019-05-11 12:24:10 some_data,some_more_data,...

2019-05-12 01:10:10 some_data,some_more_data,...
2019-05-12 12:24:10 some_data,some_more_data,...
2019-05-12 23:10:10 some_data,some_more_data,...
2019-05-12 12:24:10 some_data,some_more_data,...

Из вышеперечисленных данных, как можно отфильтровать данные, соответствующие последней отметке времени в данный день?

Я использовал несколько разборов строк и добился следующего результата - но я ищу, чтобы найти эффективный способ / альтернативы.

Итак, желаемый результат будет.

2019-05-10 19:21:10 some_data,some_more_data,...
2019-05-11 12:24:10 some_data,some_more_data,...
2019-05-12 23:10:10 some_data,some_more_data,...

Попробовал действительно уродливое разбиение строк и сравнение по времени и дате.


monday_morning_report_data = 'C:\\Users\\a071927\\Dropbox\\monday_morning_report\\monday_morning_report_data\\test.csv'


# Open CSV file in to read data from it.
open_report_file_to_read = open(monday_morning_report_data, 'r', newline='')
monday_morning_report_generation = csv.reader(open_report_file_to_read)


# Create an empty list which will gather a list of all dates only - %Y-%m-%d
list_of_all_dates = list()

# From each row of the csv file, which is a list with ONE string.
for each_timestamp_info in monday_morning_report_generation:
    # Split the string into a list.
    time_stamp_all_data = each_timestamp_info[0].split(',')
    # From the split list, get the index 0 which is the complete timestamp.
    time_stamp_info_date_time_str = time_stamp_all_data[0]
    # gather only %Y-%m-%d by splitting at ' '
    time_stamp_info_date_time_str_date_only = time_stamp_info_date_time_str.split(' ')[0]
    # if that day is not in list_of_all_dates append it.
    if time_stamp_info_date_time_str_date_only not in list_of_all_dates:
        list_of_all_dates.append(time_stamp_info_date_time_str_date_only)


# now list_of_all_Dates has the list of all unique days.
for each_day in list_of_all_dates:
    open_report_file_to_read = open(monday_morning_report_data, 'r', newline='')
    monday_morning_report_generation = csv.reader(open_report_file_to_read)

    #Gather TIMES within each unique day.
    list_of_times_in_the_given_day = list()
    # From each row of the csv file, which is a list with ONE string.
    for each_timestamp_info in monday_morning_report_generation:
        # Split the string into a list.
        time_stamp_all_data = each_timestamp_info[0].split(',')
        # From the split list, get the index 0 which is the complete timestamp.
        time_stamp_info_date_time_str = time_stamp_all_data[0]
        # gather only %Y-%m-%d by splitting at ' ' - index 0
        time_stamp_info_date_time_str_date_only = time_stamp_info_date_time_str.split(' ')[0]
        # gather only '%H:%M:%S' splitting at ' ' - index 1
        time_stamp_info_date_time_str_time_only = time_stamp_info_date_time_str.split(' ')[1]
        if each_day == time_stamp_info_date_time_str_date_only:
            list_of_times_in_the_given_day.append(time_stamp_info_date_time_str_time_only)
            #print(time_stamp_info_date_time_str_time_only)

    # initialize a max timestamp default of 00:00:00
    max_time_stamp_within_a_day = datetime.strptime('00:00:00', '%H:%M:%S')
    # initialize string with ' ' - this will be populated later.
    max_time_stamp_within_a_day_str = ''

    #Now from the list of unique times within a given day.
    for each_time in list_of_times_in_the_given_day:
        if datetime.strptime(each_time,'%H:%M:%S') >= max_time_stamp_within_a_day:
            # update the max time - date time value
            max_time_stamp_within_a_day = datetime.strptime(each_time,'%H:%M:%S')
            # update the string.
            max_time_stamp_within_a_day_str = each_time

    # once the max time / last time within a day is calculated.
    final_timestamp = each_day + ' ' + max_time_stamp_within_a_day_str

    # Print given unique day.
    print(each_day)
    # print list of times data was gathered during this day
    print(list_of_times_in_the_given_day)
    # print the final and latest timestamp.
    print(final_timestamp)

    open_report_file_to_read = open(monday_morning_report_data, 'r', newline='')
    monday_morning_report_generation = csv.reader(open_report_file_to_read)


    for each_timestamp_info in monday_morning_report_generation:
        time_stamp_all_data = each_timestamp_info[0].split(',')
        time_stamp_info_date_time_str = time_stamp_all_data[0]
        # From the final timestamp get the data.
        if time_stamp_info_date_time_str == final_timestamp:
            print(each_timestamp_info)
    print('---------')

open_report_file_to_read.close()

Есть ли эффективный способ добиться того же?

1 Ответ

2 голосов
/ 13 мая 2019

Вы можете сделать это, используя pandas. Стоит отметить, что в данных CSV нет запятой между датами и some_data. Я предварительно обработал данные, чтобы разделить их. Также обратите внимание, что приведенное ниже решение будет работать, только если данные отсортированы по дате. Если он не отсортирован, вы можете добавить df.sort_index() после вызова set_index ниже.

import pandas as pd
from dateutil.parser import parse

df = pd.read_csv('path_to_csv.csv')
df.iloc[:,0] = df.iloc[:,0].apply(parse)
df.set_index(df.columns[0], inplace=True)
indices = df.index.floor('D')
new_df = df[~indices.duplicated(keep='last') | ~indices.duplicated(keep=False)]

По сути, мы здесь выполняем синтаксический анализ столбца даты как объектов даты и времени, а затем устанавливаем его в качестве индекса DataFrame. Затем мы получаем эти индексы, доведенные до их Day. По сути, это создает Series дат, которые мы затем можем дедуплицировать и сохранять позицию последнего значения из каждого набора дубликатов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...