Python 获取错误“;ValueError:时间数据'';与格式不匹配';%Y-%m-%d%H:%m:%S'&引用;
以下是df的示例:Python 获取错误“;ValueError:时间数据'';与格式不匹配';%Y-%m-%d%H:%m:%S'&引用;,python,python-3.x,dataframe,python-datetime,Python,Python 3.x,Dataframe,Python Datetime,以下是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
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是一个人的ID,我试图检查每个ID的进入、退出和持续时间
代码如下:
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)
所以这里
是idpid
是输入时间enter\t
是退出时间exit\t
是最及时的tPS
是超时时间tLL
for
循环运行它,在该循环中,我遍历数据帧的行。因此有两个if
循环,一个带有pid
,其中一个空值表示它需要获取行[tPS]
,如果没有,则必须通过not循环运行。然后我计算持续时间,然后将这些值附加到进入-退出时间
我得到这个错误:
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'**
2019-12-02 15:04:09
---------------------------------------------------------------------------
ValueError回溯(最近的callast)
在里面
12如果行['pId']!=pid或((datetime.strftime(行['tLL'],%Y-%m-%d%H:%m:%S))
13-datetime.strftime(退出,“%Y-%m-%d%H:%m:%S”)。总秒数()>2*60*60):
--->14持续时间=(datetime.strtime(退出,“%Y-%m-%d%H:%m:%S”)-
15 datetime.strtime(输入“%Y-%m-%d%H:%m:%S”))
16输入\退出\次。追加([pid,输入\ t,退出\ t,持续时间。总\秒()
~/opt/anaconda3/lib/python3.7//u strptime.py in\u strptime\u datetime(cls,数据字符串,格式)
575“”根据输入字符串和
576格式字符串。”“”
-->577 tt,分数,gmtoff\u分数=\u strTime(数据字符串,格式)
578 tzname,gmtoff=tt[-2:]
579 args=tt[:6]+(分数,)
~/opt/anaconda3/lib/python3.7//\u strptime.py in\u strptime(数据字符串,格式)
357如果未找到:
358 raise VALUERROR(“时间数据%r与格式%r不匹配”%
-->359(数据字符串,格式))
360 if len(数据字符串)!=已找到。结束()
361 raise VALUE ERROR(“未转换的数据剩余:%s”%
**ValueError:时间数据“”与格式“%Y-%m-%d%H:%m:%S”不匹配**
错误的原因是exit_t
未在循环中的任何位置设置。它是一个空字符串。您在循环之前将其设置为exit_t=''
,但此后它将不再设置。这就是strtime
在此处引发错误的原因:
>>datetime.strtime(“”,“%Y-%m-%d%H:%m:%S”)
回溯(最近一次呼叫最后一次):
...
文件“/usr/local/ceral/python/3.7.6/Frameworks/python.framework/Versions/3.7/lib/python3.7/_strtime.py”,第359行,在_strtime中
(数据字符串,格式))
ValueError:时间数据“”与格式“%Y-%m-%d%H:%m:%S”不匹配
解决方法是将其正确设置为“tLL”
(如果我理解正确的话)
但是我想进一步说,我认为你正在使代码变得比它应该是怎样的复杂得多。我的理解是,您只需要计算“tPS”
(输入时间)和“tLL”
(输出时间)之间的持续时间。因为您已经在每一行上进行了迭代,所以只需要适当地分配值
pid = row['pId']
enter_t_str = row['tPS'] # strings
exit_t_str = row['tLL'] # strings
然后使用strtime
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_值(按=['pId','tPS','tLL'])[['pId','tPS','tLL','dZ']]
pid=“”
输入_t=“”
退出时间=“”
输入\退出\次数=[]
对于ind,stats.iterrows()中的行:
pid=行['pid']
输入\u t\u str=row['tPS']
exit_t_str=行['tLL']
输入\u t\u dt=datetime.strtime(输入\u t\u str,“%Y-%m-%d%H:%m:%S”)
exit_t_dt=datetime.strtime(exit__str,“%Y-%m-%d%H:%m:%S”)
持续时间=退出时间-输入时间
输入退出时间。追加([pid,输入退出时间,持续时间。总秒数()]))
输入\退出\次数\ df=pd.DataFrame(输入\退出\次数)
打印(输入\退出\次数\ df)
和输出数据帧:
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
试着分解你的代码。我真的觉得你自己可能甚至不理解你在那里使用的代码。把它分解,然后试着找出问题所在,这样你就可以发布一个更详细的问题。下一次,发布一些代码,不要让我们全力以赴。显示df内容,提供一个我建议在
持续时间=…
行之前打印出enter\t
和exit\t
的值。然后检查它是否与传递给strtime
的日期时间格式匹配。这非常清楚。。。非常感谢。。但是我们是否有可能每天在特定的时间对其进行过滤。。也许是早上8点到10点,看看每个PID每天在这段时间内的持续时间?@ghost22111是的,你可以datetime
对象可以像普通数字一样相互比较。您可以设置开始时间和结束时间,然后检查enter\t\u dt
是否在开始时间之后,而exit\u dt
是否在结束时间之前。请参阅我的最新答案。
if (enter_t_dt > start_dt and exit_t_dt < end_dt):
enter_exit_times.append(...)