数据挖掘 (一)——ASC文件读写、时间戳转换、可执行文件打包

一、时间戳介绍

云平台上的数据通常以timestamp为时间戳,现在有个需求,需要将timestamp时间转换成datetime时间


TimesTamp,一个能表示一份数据在某个特定时间之前已经存在的、 完整的、 可验证的数据,通常是一个字符序列,唯一地标识某一刻的时间。时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。通俗的讲, 时间戳是一份能够表示一份数据在一个特定时间点已经存在的完整的可验证的数据。 它的提出主要是为用户提供一份电子证据, 以证明用户的某些数据的产生时间。

DateTime,也就是我们平时使用的格式,例如某年某月某日某时某分,从“1000-01-01 00:00:00” 到“9999-12-31 23:59:59”之间。显然,DateTime是一个包含日期、时间的类型。

接下来获取的同一时刻的两种不同格式的时间,在Spyder开发环境里面输入以下python代码,

import  time
import datetime

print('此刻的TimesTamp时间:',time.time())
print()
print('此刻的Datatime时间:',datetime.datetime.now().strftime("%Y-%m-%d-%H:%M")  )

可以看到运行后的结果为,

此刻的TimesTamp时间: 1551497501.2004924

此刻的Datatime时间: 2019-03-02-11:31

这就是两种格式时间的区别,其实它们是一一对应的。

现在问题是这样的,由于车辆会将每秒采样到的CAN数据上传到云平台但是这种数据是以TimesTamp时间戳记录的,而我下载以后需要对该时间戳进行转换,以方便我进行数据的分析。

二、编写脚本

首先我用notepad++打开我下载的源数据文件“data.asc”,该文件里面的部分内容如下所示,

date Tue Jan 08 02:18:44 PM 2019
base hex timestamps absolute
Begin Triggerblock Tue Jan 08 02:18:44 PM 2019

  15469.19100 1  103		Rx d 8 6a 08 00 00 80 7b 0d 10
  15469.19100 1  172		Rx d 8 3c 6e 50 08 43 1c 0d 91
  15469.19100 1  266		Rx d 8 01 00 00 00 00 00 04 00
  15469.19100 1  325		Rx d 8 00 00 8e b0 b2 b4 02 00
  15469.19100 1  360		Rx d 8 fb 03 e8 0d 0e 7f 21 03
  15469.19100 1  363		Rx d 8 a6 00 10 56 00 07 01 23
  15469.19100 1  375		Rx d 8 80 00 00 00 80 00 00 00
  15469.19100 1  168		Rx d 8 8c 21 a9 46 19 09 00 03
  15469.19100 1  2a1		Rx d 8 51 02 00 00 12 01 07 92
  15469.19100 1  2a8		Rx d 8 7d 70 81 64 8b 7f f2 02
  15469.19100 1  36b		Rx d 8 81 e6 a0 79 20 88 20 7e
  15469.19100 1  374		Rx d 8 10 00 90 00 91 d1 00 00
  15469.19100 1  39e		Rx d 8 00 02 87 dc 1d 1f 13 60
  15469.19100 1  5d2		Rx d 8 52 cc cc cc cc cc cc cc
  15469.19100 1  37a		Rx d 8 7c a8 f3 cf 3c f3 cf 3c
  15469.19100 1  3ba		Rx d 8 80 02 6a 57 3f 6a 57 47

显然,第一列的timestamps数据格式有点问题,对于第一个时间15469.19100,其实1546919100才是我想要的。

我的处理思路就是,将asc文件中的内容以字符串的形式读入,这时候将会得到一个嵌套列表,其中每一个列表元素代表每一行的数据。通过提取出每一行的时间值进行处理,然后重新覆盖原来的值,最后写回asc文件。过程很简单,接下来就是实际操作啦。

在开发环境spyder中新建一个脚本文件 test.py ,编写如下代码,

# -*- coding: utf-8 -*-

import time 
from datetime import datetime
from tkinter import *
import tkinter.filedialog


def read_file(file_path):
    with open (file_path,'r') as f:
        lines = f.readlines()
    return lines
    


def modifyTimeStamp( string_data):
    
    split_line = string_data.split(' ')
    # 每一行数据都是一个字符串,
    # 以空格为切分符,对字符串进行切分,得到一个列表,
    # print(split_line),部分结果展示如下,
    # ['', '', '15469.19759', '1', '', '3cf\t\tRx', 'd', '8', '08', '24', '00', '00', '00', '00', '00', '14\n']
    # ['', '', '15469.19759', '1', '', '17a\t\tRx', 'd', '8', '4e', '4f', '4d', '00', '89', '8a', '02', '00\n']
    
    temp_1 = int(split_line[2][0:5])
    # 取出时间值中小数点前的数字
    # print(temp_1) ,部分结果展示如下,
    # 15469
    # 15469
    
    temp_2 = int(split_line[2][6:11])
    # 取出时间值中小数点后的数字
    # print(temp_2) ,部分结果展示如下,
    # 19759
    # 19759

    new_temp_2  = "%05d"  % temp_2
    # 防止第一位数字为0时被剔除掉,即防止09759被强制保留为9759
    
    converted_time = str( temp_1) + new_temp_2  
    # 对小数点前和后的数字重新拼接,拼接前先字符串化                    
                        
    localTime = time.localtime(int(converted_time) ) 
    strTime = time.strftime("%Y-%m-%d %H:%M:%S", localTime) 
    # 将timestamps时间转换为Datetime时间,
    # 再将Datetime时间按照我们设置的格式(即"%Y-%m-%d %H:%M:%S")输出
    # print(strTime),部分结果展示如下,
    # 2019-01-08 11:55:59
    # 2019-01-08 11:55:59
     
    return split_line,strTime




if __name__ == "__main__":
    
    start_time = time.time()
    # 记录程序运行时的起止时间
     
    root = Tk()           
    # 创建一个Tkinter.Tk()实例
    
    root.withdraw()   
    # 将Tkinter.Tk()实例隐藏
    
    input_file = tkinter.filedialog.askopenfilename(title=u'选择文件')  
    # 以对话框的形式选择一个文件,并返回其绝对路径,保存在变量filenames中
    
    data_lines = read_file(input_file)
    # 读入asc源数据文件

    output_file = tkinter.filedialog.asksaveasfilename(title=u'保存文件')
    # 以对话框的形式选择用于保存结果的文件名,并返回其绝对路径,保存在变量output_file中
    
    print('已读取完毕,文件总行数为:%d' %len(data_lines))

    with open(output_file,'w') as fp:  
        
        for i in range(len(data_lines)):
            
            if i > 3:
                split_line,strTime = modifyTimeStamp( data_lines[i] )       
                
                split_line[2] = strTime
                # 用转换后得到的Datetime值替换原来的timestamps值
                          
                s2 = " ".join([e for e in split_line])  
                # 将列表中的所有字符串元素连接起来,变成一个长长的字符串      
                #print(s2)
                # 部分结果展示如下:
                # 2019-01-08 11:55:34 1  380            Rx d 8 03 00 51 00 39 00 00 00
                # 2019-01-08 11:55:34 1  324            Rx d 8 40 64 07 d0 00 30 0a 6f
                
                fp.write(s2)
                # 写入文件
                
            else:
                fp.write(data_lines[i])
            # 前三行是备注信号,按照原样写入
                
    print('时间戳转换成功!!')
    print("--- 花费时间 %s seconds ---" % (time.time() - start_time)) 
    # 记录程序运行完毕时的时间,再减去起始时间,得到脚本运行所用的时间

三、运行结果

运行脚本以后,首先会弹出一个对话框,让你选择待读取的文件,然后又会弹出一个对话框,再次让你选择一个用于保存结果的文件,如下图所示,
数据挖掘 (一)——ASC文件读写、时间戳转换、可执行文件打包_第1张图片
数据挖掘 (一)——ASC文件读写、时间戳转换、可执行文件打包_第2张图片

最后,打开我用于保存结果的result.asc文件,可以看到里面的部分内容为,

date Tue Jan 08 02:18:44 PM 2019
base hex timestamps absolute
Begin Triggerblock Tue Jan 08 02:18:44 PM 2019

  2018-12-28 22:58:20 1  103		Rx d 8 6a 08 00 00 80 7b 0d 10
  2018-12-28 22:58:20 1  172		Rx d 8 3c 6e 50 08 43 1c 0d 91
  2018-12-28 22:58:20 1  266		Rx d 8 01 00 00 00 00 00 04 00
  2018-12-28 22:58:20 1  325		Rx d 8 00 00 8e b0 b2 b4 02 00
  2018-12-28 22:58:20 1  360		Rx d 8 fb 03 e8 0d 0e 7f 21 03
  2018-12-28 22:58:20 1  363		Rx d 8 a6 00 10 56 00 07 01 23
  2019-01-08 11:45:00 1  375		Rx d 8 80 00 00 00 80 00 00 00
  2019-01-08 11:45:00 1  168		Rx d 8 8c 21 a9 46 19 09 00 03
  2019-01-08 11:45:00 1  2a1		Rx d 8 51 02 00 00 12 01 07 92
  2019-01-08 11:45:00 1  2a8		Rx d 8 7d 70 81 64 8b 7f f2 02

四、pyinstaller将脚本打包成.exe的可执行文件

PyInstaller 是一个十分有用的第三方库,它能够在Windows、Linux、 Mac OS X 等操作系统下将 Python 源文件打包,通过对源文件打包, Python 程序可以在没有安装 Python 的环境中运行,也可以作为一个独立文件方便传递和管理。但是要注意版本的问题,之前因为python版本太高,装的是3.7,怎么搞都不行。之后降到3.6才可以,后来才发现,pyinstaller最高支持3.6。

首先要确保已经安装好 pyinstaller 模块,这个很简单,只需要进入cmd,使用pip命令安装:pip install PyInstaller即可。列出 pyinstaller 的常用参数,常用的如下:

  • -F 表示生成单个可执行文件
  • -w 表示去掉控制台窗口,这在GUI界面时非常有用。不过如果是命令行程序的话那就把这个选项删除吧!
  • -p 表示你自己自定义需要加载的类路径,一般情况下用不到
  • -i 表示可执行文件的图标

然后在cmd中进入脚本所在的目录,输入以下内容(最后的是文件名), Pyinstaller -F -w test.py即可。

执行完毕后,源文件所在目录将生成 dist 和 build 两个文件夹。 其中,build 目录是 pyinstaller 存储临时文件的目录,可以安全删除。最终的打包程序在 dist 文件夹中。如下所示,

数据挖掘 (一)——ASC文件读写、时间戳转换、可执行文件打包_第3张图片
这就是生成的可执行文件
至此,简单的任务就完成了。

你可能感兴趣的:(数据挖掘)