以下内容总结了之前章节涉及到的 Python 知识点,看过之前的章节同学,就不用打开了。

1. Restful 访问 TDengine 数据库

知识点:

  • 发送给 TDengine 的 HTTP Body 里面是 SQL 明文,请求方式为 POST。
  • TDenging 返回的结果是 JSON 格式。
  • 如果写入的数据包含中文,那么必须对 SQL 进行 encode("UTF-8")
def request_post(url, sql, user, pwd):
    try:
        sql = sql.encode("utf-8")
        headers = {
            'Connection': 'keep-alive',
            'Accept-Encoding': 'gzip, deflate, br'
        }
        result = requests.post(url, data=sql, auth=HTTPBasicAuth(user,pwd),headers=headers)
        text=result.content.decode()
        return text
    except Exception as e:
        print(e)

def request_get(resInfo):
    load_data = json.loads(resInfo)
    data = load_data.get("data")
    return data        

2. SQL 拼接

如果要高效写入 TDengine,需要将多条记录拼接成一条 SQL(SQL 长度不能超过 1MB)。
以下程序会对一个二维数组进行遍历,逐个拼接成一条 SQL 并返回。

def join_sql(dbname,tbname,datalist):
    sql = 'insert into '+dbname+'.'+tbname+" values"
    for i in range(len(datalist)):
        sql = sql + '('
        for l in range(len(datalist[i])):
            if l == 0:
                sql = sql +'"'+str(datalist[i][l])+'"'
            else:
                sql = sql + str(datalist[i][l]) 
            if l <= len(datalist[i])-2:
                sql = sql + ','
        sql = sql + ')'
    return sql

3. 多线程/进程

为提过程序的执行效率,可以采用多线程或多进程的方式。
以下程序对数组 flist 按照并发数 threadNum 进行分割,每个子线程/进程对传递的数组进行遍历,对每个值调用 csv_read 函数进行处理。

def thread_func(flist,tnum,list_num):
    for ll in range(list_num):
        ii=tnum*list_num+ll
        if ii < len(flist):
            filename = str(flist[ii][0])
            csv_read(filename)

def multi_thread(flist,wmethod):
    threads = []
    if len(flist) < threadNum:
        for i in range(len(flist)):
            filename = flist[i][0]
            csv_read(filename)
    else:
        listnum = int(len(flist)/threadNum)+1
        if wmethod == 'process':
            for tnum in range(threadNum):  
                t = multiprocessing.Process(target=thread_func,args=(flist,tnum,listnum))
                threads.append(t)
        else:
            for tnum in range(threadNum):             
                t = threading.Thread(target=thread_func,args=(flist,tnum,listnum))
                threads.append(t)
        for t in threads:  
            t.start()
        for t in threads:  
            t.join()

4. 绘图

绘图需要使用 matplotlib 模块。
知识点:

  • 绘制多个子图 plt.subplot(3, 1, 1)
  • 绘制曲线 plt.plot(df.index, df['close'])
  • 绘制柱状图 plt.bar(range(len(profits)),profits)
  • x轴名称 plt.xlabel('tdate')
  • x轴名称 plt.ylabel('Price')

以下示例在一个图片里面绘制了收盘价、MACD、收益曲线三个子图。

plt.figure(figsize=(12, 8))
plt.subplot(3, 1, 1)
plt.plot(df.index, df['close'])
plt.title(fcode)
plt.xlabel('tdate')
plt.ylabel('Price')


plt.subplot(3, 1, 2)
plt.title("MACD")
plt.plot(df['DIF'],'r',linewidth=1.0,label='DIF')
plt.plot(df['DEA'],'y',linewidth=1.0,label='DEA')
plt.legend()
plt.grid()

plt.subplot(3, 1, 3)
plt.title("收益曲线")
plt.plot(profits,'r',linewidth=1.0,label='Profit')
plt.bar(range(len(profits)),profits)
plt.ylabel('RMB')
plt.legend()
plt.grid()


plt.tight_layout()
plt.show()

如果要显示中文,则需要进行如下设置:

matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['font.family']='sans-serif'
matplotlib.rcParams['axes.unicode_minus'] = False  
11-14 07:09