Python 从字符串(或DataFrame对象)提取时间数据的更有效方法
我正在自学Python,这是我在这里的第一个问题。总是能够找到所有需要的答案。终于得到了一些我认为值得问的问题。这只是更具体的任务,我甚至不知道该搜索什么 我们的一台机器正在生成一个日志文件,这需要在加载到数据帧之后和能够使用之前进行大量清理。在不涉及太多细节的情况下,日志文件包含格式非常奇怪的时间记录。它由分、秒和毫秒组成。我能够使用下面显示的函数将其解码为秒(并用另一个函数将其进一步转换为时间格式)。它工作得很好,但是这是一个非常基本的函数,有很多if语句 我的目标是把它改写成不那么业余的样子,但是日志时间格式至少对我来说有一些挑战性的限制。即使单位是两个字母的组合,也无济于事 以下是所有可能的时间记录组合示例:Python 从字符串(或DataFrame对象)提取时间数据的更有效方法,python,python-3.x,dataframe,Python,Python 3.x,Dataframe,我正在自学Python,这是我在这里的第一个问题。总是能够找到所有需要的答案。终于得到了一些我认为值得问的问题。这只是更具体的任务,我甚至不知道该搜索什么 我们的一台机器正在生成一个日志文件,这需要在加载到数据帧之后和能够使用之前进行大量清理。在不涉及太多细节的情况下,日志文件包含格式非常奇怪的时间记录。它由分、秒和毫秒组成。我能够使用下面显示的函数将其解码为秒(并用另一个函数将其进一步转换为时间格式)。它工作得很好,但是这是一个非常基本的函数,有很多if语句 我的目标是把它改写成不那么业余的样
test1 = 'T#3853m10s575ms' # 231190.575 [seconds]
test2 = 'T#10s575ms' # 10.575
test3 = 'T#3853m575ms' # 231180.575
test4 = 'T#575ms' # 0.575
test5 = 'T#3853m10s' # 231190
test6 = 'T#10s' # 10
test7 = 'T#3853m' # 231180
test8 = 'T#0ms' # 0
我尝试用正则表达式格式编写它,如下所示:
T#[0-9]*m?[0-9]*s?[0-9]*ms?
但是,始终至少存在一个数字和至少一个单元
下面是我在函数中使用的逻辑:
下面是我应用于数据帧中原始时间列的函数:
def convert_time(string):
if string == 'T#0ms':
return 0
else:
ms_ = False if string.find('ms') == -1 else True
string = string[2:-2] if ms_ else string[2:]
s_ = False if string.find('s') == -1 else True
m_ = False if string.find('m') == -1 else True
if m_ and s_ and ms_:
m, temp = string.split('m')
s, ms = temp.split('s')
return int(m)*60 + int(s) + int(ms)*0.001
elif not m_ and s_ and ms_:
s, ms = string.split('s')
return int(s) + 0.001 * int(ms)
elif m_ and not s_ and ms_:
m, ms = string.split('m')
return 60*int(m) + 0.001 * int(ms)
elif not m_ and not s_ and ms_:
return int(string) * 0.001
elif m_ and s_ and not ms_:
m, s = string.split('m')
return 60*int(m) + int(s[:-1])
elif not m_ and s_ and not ms_:
return int(string[:-1])
elif m_ and not s_ and not ms_:
return int(string[:-1]) * 60
elif not m_ and not s_ and not ms_:
return -1
如上所述,由于缺乏经验,我无法编写更好的函数来产生类似的输出(或者更好,例如直接以时间格式)。
希望这将是有趣的足够得到一些改进提示。谢谢。使用正则表达式:
def str_to_sec(time_str):
return_int = 0
cur_int = 0
# remove start characters and replace 'ms' with a single character as unit
time_str = time_str.replace('T#','').replace('ms', 'p')
# build multiplier matrix
split_order = ['m', 's', 'p']
multiplier = [60, 1, 0.001]
calc_multiplier_dic = dict(zip(split_order, multiplier))
# loop through string and update the cumulative time
for ch in time_str:
if ch.isnumeric():
cur_int = cur_int * 10 + int(ch)
continue
if ch.isalpha():
return_int += cur_int * calc_multiplier_dic[ch]
cur_int = 0
return return_int
import re
def f(x):
x = x[2:]
time = re.findall(r'\d+', x)
timeType = re.findall(r'[a-zA-Z]+',x)
#print(time,timeType)
total = 0
for i,j in zip(time,timeType):
if j == 'm':
total += 60*float(i)
elif j =='s':
total+=float(i)
elif j == 'ms':
total += float(i)/1000
return total
test1 = 'T#3853m10s575ms' # 231190.575 [seconds]
test2 = 'T#10s575ms' # 10.575
test3 = 'T#3853m575ms' # 231180.575
test4 = 'T#575ms' # 0.575
test5 = 'T#3853m10s' # 231190
test6 = 'T#10s' # 10
test7 = 'T#3853m' # 231180
test8 = 'T#0ms' # 0
arr = [test1,test2,test3,test4,test5,test6,test7,test8]
for t in arr:
print(f(t))
输出:
231190.575
10.575
231180.575
0.575
231190.0
10.0
231180.0
0.0
[Finished in 0.7s]
或者,如果您有更多的时间类型,如一小时、一天等,则可以缩小代码的外观。使用地图
import re
def symbol(j):
if j == 'm':
return 60
elif j =='s':
return 1
elif j == 'ms':
return .001
def f(x):
x = x[2:]
time = list(map(float,re.findall(r'\d+', x)))
timeType = list(map(symbol,re.findall(r'[a-zA-Z]+',x)))
#print(time,timeType)
return sum([a*b for a,b in zip(timeType,time)])
test1 = 'T#3853m10s575ms' # 231190.575 [seconds]
test2 = 'T#10s575ms' # 10.575
test3 = 'T#3853m575ms' # 231180.575
test4 = 'T#575ms' # 0.575
test5 = 'T#3853m10s' # 231190
test6 = 'T#10s' # 10
test7 = 'T#3853m' # 231180
test8 = 'T#0ms' # 0
arr = [test1,test2,test3,test4,test5,test6,test7,test8]
for t in arr:
print(f(t))