Как очистить строки даты и времени в кадре данных после экспорта из таблицы Excel? - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть таблица Excel с некоторыми данными о времени и дате в столбце.Я экспортировал данные в фрейм данных, используя панд.Однако в этом столбце содержатся фрагменты дат, у которых поменялись местами месяц и день, а в этом же столбце есть и другие правильные фрагменты дат.Вот пример -

enter image description here

Рисунок 1: День и месяц поменялись местами неверно

На приведенном выше рисунке показаны день и месяц, поменялись местами,Дата показывает 2016-01-10, но вместо этого должна быть 2016-10-01.Сравните это с другой порцией значений даты и времени в том же столбце -

enter image description here

Рисунок 2. День и месяц правильно представлены

InВ приведенном выше примере на рисунке 2 месяц правильно представлен как 12, а день - 31.

Я использовал решение этого вопроса - Как поменять месяцы и дни в объекте datetime?

Я также пытался использовать это решение - Python Pandas - день и месяц смешиваются

Я также пытался написать свою собственную функцию для сопоставления с записями, ноэто также не помогло -

def dm_swap(day, month):
if(month != 10 or month != 11 or month != 12):
    temp = day
    day = month
    month = temp

t2016Q4.start.map(dmswap, t2016Q4.dt.day, t2016Q4.dt.month)

Однако оба решения изменяют все значения даты и времени в столбце.Таким образом, когда неправильные значения исправляются, правильные значения становятся неправильными.

Я также связал файл excel для вашего удобства.Это открытый набор данных.

https://www.toronto.ca/city-government/data-research-maps/open-data/open-data-catalogue/#343faeaa-c920-57d6-6a75-969181b6cbde

Пожалуйста, выберите последний набор данных Bikeshare Ridership (2016 Q4).Столбцы «начало» и «конец» имеют вышеуказанные проблемы.

Есть ли более эффективный способ очистки данных даты и времени?

Ответы [ 3 ]

0 голосов
/ 27 ноября 2018

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

Вот быстрый способ "перевернуть "все даты.Недопустимые даты приводятся к значениям NaT (Not-A-Timestamp) и затем удаляются.Затем оставшиеся перевернутые даты можно переназначить на df:

import pandas as pd

df = pd.read_excel('2016_Bike_Share_Toronto_Ridership_Q4.xlsx')

for col in ['trip_start_time', 'trip_stop_time']:
    df[col] = pd.to_datetime(df[col])
    swapped = pd.to_datetime({'year':df[col].dt.year, 
                              'month':df[col].dt.day, 
                              'day':df[col].dt.month,
                              'hour':df[col].dt.hour,
                              'minute':df[col].dt.minute,
                              'second':df[col].dt.second,}, errors='coerce')
    swapped = swapped.dropna()
    mask = swapped.index
    df.loc[mask, col] = swapped

# check that now all dates are in 2016Q4
for col in ['trip_start_time', 'trip_stop_time']:
    mask = (pd.PeriodIndex(df[col], freq='Q') == '2016Q4')
    assert mask.all()

# check that `trip_start_times` are in chronological order
assert (df['trip_start_time'].diff().dropna() >= pd.Timedelta(0)).all()

# check that `trip_stop_times` are always greater than `trip_start_times`
assert ((df['trip_stop_time']-df['trip_start_time']).dropna() >= pd.Timedelta(0)).all()

Приведенные выше утверждения assert подтверждают, что все результирующие даты находятся в 2016Q4, что trip_start_times в хронологическом порядке и что trip_stop_times всегда больше, чем связанные trip_start_times.

0 голосов
/ 28 ноября 2018

Вы можете использовать параметр format в pd.to_datetime:

>>> date= pd.Series(['2016-01-10', '2016-02-10'])
>>> pd.to_datetime(date, format='%Y-%d-%m')
Out: 
0   2016-10-01
1   2016-10-02
0 голосов
/ 27 ноября 2018

ОК.

РЕДАКТИРОВАТЬ - снова.Я запустил код ниже, и это заняло вечность!В конце я прервался, но это определенно работает и в разумное время - удачи!ранее, новый код здесь:

import pandas as pd

f = "string\to\file\here.xlsx"
df = pd.read_excel(f)

for idx in df.index:
    trip_start = df.loc[df.index[idx], "trip_start_time"]
    trip_end = df.loc[df.index[idx], "trip_stop_time"]
    start_dt = trip_start.to_datetime()
    end_dt = trip_end.to_datetime()
    try:
        start_dt_string = start_dt.strftime("%Y-%d-%m %H:%M:%S")
        end_dt_string = end_dt.strftime("%Y-%d-%m %H:%M:%S")
        start_ts = pd.Timestamp(start_dt_string)
        end_ts = pd.Timestamp(end_dt_string)
        df.loc[idx, "trip_start_time"] = start_ts
        df.loc[idx, "trip_stop_time"] = end_ts
    except ValueError:
        pass

Это немного медленно (есть куча строк данных), но мой компьютер, кажется, работает через него - обновится снова, если не получится.

Старый ответ: Итак, все, что произошло, заключается в том, что каждая дата / время, когда нет возможности двусмысленности, содержится в исходном наборе данных в формате: ДД / ММ / ГГГГ ЧЧ: ММ: СС.

Если это возможночтобы привести к MM / DD / YY HH: MM: SS, тогда у него есть

Что бы я сделал, это перебрать каждый столбец

for row in df.index:
    try:
        new_dt = datetime.strptime(row, "%Y-%d-%m %H:%M:%S")
        #write back to the df here
    except ValueError:
        pass#ignore anything  that cannot be converted
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...