2016-05-28 3 views
1

У меня есть кадр данных со столбцом дат начала и столбцом дат окончания. Я хочу проверить целостность дат, гарантируя, что дата начала до даты окончания (т. Е. Start_date < end_date). У меня есть более 14 000 наблюдений.Эффективно сравнивать каждую пару дат в двух столбцах в python

У меня есть данные в виде:

Start  End 
0 2008-10-01 2008-10-31 
1 2006-07-01 2006-12-31 
2 2000-05-01 2002-12-31 
3 1971-08-01 1973-12-31 
4 1969-01-01 1969-12-31 

Я добавил колонку, чтобы написать результат, даже если я просто хочу подчеркнуть, есть ли некорректные те, так что я могу удалить их:

dates['Correct'] = " " 

И уже начал проверять каждую пару дат, используя следующий, где мой dataframe называется дата:

for index, row in dates.iterrows(): 
    if dates.Start[index] < dates.End[index]: 
     dates.Correct[index] = "correct" 
    elif dates.Start[index] == dates.End[index]: 
     dates.Correct[index] = "same" 
    elif dates.Start[index] > dates.End[index]: 
     dates.Correct[index] = "incorrect" 

Что работает, это просто очень долгое время (около 15 минут). Мне нужен более эффективный код - есть ли что-то, что я делаю неправильно или могу улучшить?

+1

Удалите это последнее 'elif' и замените его' else' – Deepanshu

ответ

2

Почему бы просто не сделать это в векторном виде:

is_correct = dates['Start'] < dates['End'] 
is_incorrect = dates['Start'] > dates['End'] 
is_same = ~is_correct & ~is_incorrect 
+0

Спасибо! Так просто, так быстро! – emboylen

1

Поскольку список не нужно сравнивать последовательно, вы можете увеличить производительность, разделив ваш набор данных, а затем используя несколько процессов для одновременного сравнения. Взгляните на модуль multiprocessing.

0

Что-то вроде следующего может быть быстрее:

import pandas as pd 
import datetime 

df = pd.DataFrame({ 
    'start': ["2008-10-01", "2006-07-01", "2000-05-01"], 
    'end': ["2008-10-31", "2006-12-31", "2002-12-31"], 
}) 


def comparison_check(df): 
    start = datetime.datetime.strptime(df['start'], "%Y-%m-%d").date() 
    end = datetime.datetime.strptime(df['end'], "%Y-%m-%d").date() 
    if start < end: 
     return "correct" 
    elif start == end: 
     return "same" 
    return "incorrect" 

In [23]: df.apply(comparison_check, axis=1) 
Out[23]: 
0 correct 
1 correct 
2 correct 
dtype: object 

Timings

In [26]: %timeit df.apply(comparison_check, axis=1) 
1000 loops, best of 3: 447 µs per loop 

Так по моим расчетам, 14,000 строк следует принимать (447/3) * 14,000 = (149 мкс) * 14,000 = 2,086s, поэтому может быть менее 15 минут :)