Ошибка «ValueError: данные времени» не соответствует формату «% Y-% m-% d% H:% M:% S» - PullRequest
0 голосов
/ 09 января 2020

Вот пример df:

pId tPS                 tLL                 dZ
129 2019-12-02 15:04:09 2019-12-02 15:06:31 5f723
129 2019-12-02 15:04:15 2019-12-02 15:06:37 5f723
129 2019-12-02 15:05:15 2019-12-02 15:07:37 5f723
129 2019-12-02 15:05:18 2019-12-02 15:07:40 5f723
129 2019-12-02 15:05:24 2019-12-02 15:07:46 5f723

pID - это идентификатор человека, и я пытаюсь проверить время входа, выхода и продолжительность для каждого идентификатора.

Вот код:

from datetime import datetime
stats=df.sort_values(by=['pId', 'tPS', 'tLL'])[['pId', 'tPS', 'tLL', 'dZ']]
pid = ''
enter_t = ''
exit_t = ''

enter_exit_times=[]

for ind, row in stats.iterrows():

    if pid =='':
        enter_t = row['tPS']
        print(enter_t)

    if row['pId']!= pid or ((datetime.strftime(row['tLL'], "%Y-%m-%d %H:%M:%S") 
                         - datetime.strftime(exit_t, "%Y-%m-%d %H:%M:%S")).total_seconds()>2*60*60):

    duration = (datetime.strptime(exit_t, "%Y-%m-%d %H:%M:%S") -
                datetime.strptime(enter_t, "%Y-%m-%d %H:%M:%S"))

    enter_exit_times.append([pid, enter_t, exit_t, duration.total_seconds()])

    pid = row['pId']

    enter_t = row['tPS']

enter_exit_times.append([pid, enter_t, exit_t])
enter_exit_times_df = pd.DataFrame(enter_exit_times)

Так вот

  • pid - это идентификатор
  • enter_t - это время входа
  • exit_t - это время выхода
  • tPS - это время выхода
  • tLL - это время выхода.

Затем я создаю список для которого я пишу все oop ниже. Сначала я запускаю его через for l oop, где я перебираю строки фрейма данных. Таким образом, есть два if l oop, один с pid, где пустое значение означает, что он должен взять row[tPS], а если нет, то он должен пройти через не l oop. Затем я вычисляю продолжительность, а затем добавляю значения ко времени входа-выхода.

Я получаю эту ошибку:

2019-12-02 15:04:09
---------------------------------------------------------------------------
ValueError                           Traceback (most recent callast)
<ipython-input-411-fd8f6f998cc8> in <module>
12     if row['pId']!= pid or ((datetime.strftime(row['tLL'], "%Y-%m-%d %H:%M:%S") 
13                              - datetime.strftime(exit_t, "%Y-%m-%d %H:%M:%S")).total_seconds()>2*60*60):
---> 14         duration = (datetime.strptime(exit_t, "%Y-%m-%d %H:%M:%S") -
15                     datetime.strptime(enter_t, "%Y-%m-%d %H:%M:%S"))
16         enter_exit_times.append([pid, enter_t, exit_t, duration.total_seconds()])

~/opt/anaconda3/lib/python3.7/_strptime.py in _strptime_datetime(cls, data_string, format)
575     """Return a class cls instance based on the input string and the
576     format string."""
--> 577     tt, fraction, gmtoff_fraction = _strptime(data_string, format)
578     tzname, gmtoff = tt[-2:]
579     args = tt[:6] + (fraction,)

~/opt/anaconda3/lib/python3.7/_strptime.py in _strptime(data_string, format)
357     if not found:
358         raise ValueError("time data %r does not match format %r" %
--> 359                          (data_string, format))
360     if len(data_string) != found.end():
361         raise ValueError("unconverted data remains: %s" %

**ValueError: time data '' does not match format '%Y-%m-%d %H:%M:%S'**

1 Ответ

1 голос
/ 10 января 2020

Причина ошибки в том, что exit_t не установлен в любом месте в l oop. Это пустая строка. Вы устанавливаете его до l oop на exit_t = '', но затем оно никогда не устанавливается снова Вот почему strptime выдает ошибку здесь:

>>> datetime.strptime(' ', "%Y-%m-%d %H:%M:%S")
Traceback (most recent call last):
...
  File "/usr/local/Cellar/python/3.7.6/Frameworks/Python.framework/Versions/3.7/lib/python3.7/_strptime.py", line 359, in _strptime
    (data_string, format))
ValueError: time data ' ' does not match format '%Y-%m-%d %H:%M:%S'

Решение состоит в том, чтобы просто установить его правильно на "tLL" (если я вас правильно понимаю).

Но я бы хотел go далее и скажу, что я думаю, что вы делаете код намного намного более сложным, чем это должно быть. Насколько я понимаю, вы просто хотите вычислить продолжительность времени между "tPS" (время на входе) и "tLL" (время на выходе). Поскольку вы уже выполняете итерацию по каждой строке, вам просто нужно присвоить значения соответствующим образом

pid = row['pId']

enter_t_str = row['tPS']  # strings
exit_t_str = row['tLL']   # strings

, затем преобразовать строки datetime в объекты datetime, используя strptime

enter_t_dt = datetime.strptime(enter_t_str, "%Y-%m-%d %H:%M:%S")
exit_t_dt = datetime.strptime(exit_t_str, "%Y-%m-%d %H:%M:%S")

, а затем вычислить Продолжительность

duration = exit_t_dt - enter_t_dt

и, наконец, добавьте его в свой список

enter_exit_times.append([pid, enter_t_str, exit_t_str, duration.total_seconds()])

Нет необходимости отслеживать "pId".

Вот полный код:

stats = df.sort_values(by=['pId', 'tPS', 'tLL'])[['pId', 'tPS', 'tLL', 'dZ']]

pid = ''
enter_t = ''
exit_t = ''
enter_exit_times = []

for ind, row in stats.iterrows():
    pid = row['pId']

    enter_t_str = row['tPS']
    exit_t_str = row['tLL']

    enter_t_dt = datetime.strptime(enter_t_str, "%Y-%m-%d %H:%M:%S")
    exit_t_dt = datetime.strptime(exit_t_str, "%Y-%m-%d %H:%M:%S")
    duration = exit_t_dt - enter_t_dt

    enter_exit_times.append([pid, enter_t_str, exit_t_str, duration.total_seconds()])

enter_exit_times_df = pd.DataFrame(enter_exit_times)
print(enter_exit_times_df)

И выходной DataFrame:

     0                    1                    2      3
0  129  2019-12-02 15:04:09  2019-12-02 15:06:31  142.0
1  129  2019-12-02 15:04:15  2019-12-02 15:06:37  142.0
2  129  2019-12-02 15:05:15  2019-12-02 15:07:37  142.0
3  129  2019-12-02 15:05:18  2019-12-02 15:07:40  142.0
4  129  2019-12-02 15:05:24  2019-12-02 15:07:46  142.0

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

>>> dt_beg = datetime(2019,12,2,8,0,0)   #8AM
>>> dt_beg
datetime.datetime(2019, 12, 2, 8, 0)
>>> dt_end = datetime(2019,12,2,10,0,0)  #10AM
>>> dt_end
datetime.datetime(2019, 12, 2, 10, 0)
>>> dt = datetime(2019,12,2,9,34,0)      #9:34AM
>>> dt_beg < dt < dt_end
True
>>> dt = datetime(2019,12,2,14,34,0)     #2:34PM
>>> dt_beg < dt < dt_end
False

Таким образом, вы можете добавить фильтр для того, что добавить к enter_exit_times:

if (enter_t_dt > start_dt and exit_t_dt < end_dt):
    enter_exit_times.append(...)
...