教你如何在 Windows 下让崩溃的 Python 程序自重启

我们用Python定时跑一些自动化程序的时候会出现程序崩溃的情况。此时如果你本人不在电脑面前,或者没有留意到程序的崩溃,没有及时重新拉起程序,会造成或大或小的损失。

本文将教你如何在 Windows 下使用 Supervisor 重新拉起崩溃的Python程序。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install supervisor-win

如果你出现 “DLL load failed: 找不到指定的程序” 的报错,请重新安装pywin32:

pip install pywin32==223

2.编写自重启配置

接下来,你需要编写一个让你的Python程序自动运行,遇到报错自动重启的配置:

[program:cancel]
command=G:\\Anaconda3\\envs\\tdx_easytrader\\python.exe D://CODE//tdx_easytrader//dataserver.py
    
[supervisord]
nodaemon=true

[supervisorctl]

前两行就是你的程序运行命令,在上面的例子中,program: 后面的关键词是你自定义的程序名,我的Python位于 G:\Anaconda3\envs\tdx_easytrader\python.exe,我想要自重启的脚本位于 D://CODE//tdx_easytrader//dataserver.py

此外,后面的三行是必须配置的,按我的默认写法即可。

编写完成后将配置命名为 supervisord.conf 保存于任何地方,可以是项目目录下,也可以是一个重要的配置目录文件夹。

然后执行以下命令启动 supervisord:

supervisord -c D:\CODE\tdx_easytrader\supervisord.conf

注意 -c 参数后就是你的 supervisord.conf 的绝对路径。启动完毕显示:

2022-06-27 19:58:54,809 INFO process group added: 'cancel'
2022-06-27 19:58:54,810 INFO supervisord started with pid 28472
2022-06-27 19:58:54,815 INFO Spawned: 'cancel' with pid 27220
2022-06-27 19:58:55,830 INFO success: cancel entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

意思是,supervisord 进程已经启动,pid为28472。我命名为cancel的Python进程也已经启动,pid为27220。我们在任务管理器中可以查看到这两个进程:

3.测试

接下来我们测试一下它能否自动重启,让我们强杀 27220 这个进程,观察终端:

2022-06-27 19:58:54,815 INFO Spawned: 'cancel' with pid 27220
2022-06-27 19:58:55,830 INFO success: cancel entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2022-06-27 20:02:58,077 INFO exited: cancel (exit status 1; not expected)
2022-06-27 20:02:58,590 INFO Spawned: 'cancel' with pid 16640
2022-06-27 20:02:59,603 INFO success: cancel entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

可以看到, 20:02:58秒的时候 cancel 程序意外退出(exit status 1; not expected),然后supervisord重新帮我们拉起了一个cancel程序,pid为16640:

测试成功,程序成功自重启。

Supervisor不仅会把日志输出到终端中,在你运行命令的目录中,它还会生成supervisord.log, 这里面也保存了所有运行日志:

当然,在上方我们supervisord的配置里,你也能配置日志输出位置、最大大小、分片数量等:

[supervisord]
logfile = /tmp/supervisord.log
logfile_maxbytes = 50MB
logfile_backups=10
loglevel = info
pidfile = /tmp/supervisord.pid

Supervisord 还有许多其他的功能,有兴趣的同学可以访问他们官网查询:

http://supervisord.org/introduction.html

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

这个神器能帮你自动识别文字中的省市区并绘图

在做NLP(自然语言处理)相关任务时,经常会遇到需要识别并提取省、城市、行政区的需求。虽然我们自己通过关键词表一个个查找也能实现提取目的,但是需要先搜集省市区关键词表,相对而言比较繁琐。

今天给大家介绍一个模块,你只需要把字符串传递给这个模块,他就能给你返回这个字符串内的省、市、区关键词,并能给你在图片上标注起来,它就是 Cpca 模块。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install cpca

注意,目前 cpca 模块仅支持Python3及以上版本。

在 windows 上可能会出现类似如下问题

Building wheel for pyahocorasick (setup.py) ... error

先去下载 Microsoft Visual C++ Build Tools 安装VC++构建工具,再重新 pip install cpca,即可解决问题

2.基本使用

通过两行代码就能实现最基本的省市区提取:

# 公众号: Python 实用宝典
# 2022/06/23

import cpca

location_str = [
    "广东省深圳市福田区巴丁街深南中路1025号新城大厦1层",
    "特斯拉上海超级工厂是特斯拉汽车首座美国本土以外的超级工厂,位于中华人民共和国上海市。",
    "三星堆遗址位于中国四川省广汉市城西三星堆镇的鸭子河畔,属青铜时代文化遗址"
]
df = cpca.transform(location_str)
print(df)

效果如下:

     省     市     区                     地址  adcode
0  广东省   深圳市   福田区     巴丁街深南中路1025号新城大厦1层  440304
1  上海市  None  None                      。  310000
2  四川省   德阳市   广汉市  城西三星堆镇的鸭子河畔,属青铜时代文化遗址  510681

注意第三条的广汉市,cpca 不仅识别到了语句中的县级市广汉市,还能自动匹配到其代管市的德阳市,不得不说非常强大。

如果你想获知程序是从字符串的那个位置提取出省市区名的,可以添加一个 pos_sensitive=True 参数:

# 公众号: Python 实用宝典
# 2022/06/23

import cpca

location_str = [
    "广东省深圳市福田区巴丁街深南中路1025号新城大厦1层",
    "特斯拉上海超级工厂是特斯拉汽车首座美国本土以外的超级工厂,位于中华人民共和国上海市。",
    "三星堆遗址位于中国四川省广汉市城西三星堆镇的鸭子河畔,属青铜时代文化遗址"
]
df = cpca.transform(location_str, pos_sensitive=True)
print(df)

效果如下:

(base) G:\push\20220623>python 1.py
     省     市     区                     地址  adcode  省_pos  市_pos  区_pos
0  广东省   深圳市   福田区     巴丁街深南中路1025号新城大厦1层  440304      0      3      6
1  上海市  None  None                      。  310000     38     -1     -1
2  四川省   德阳市   广汉市  城西三星堆镇的鸭子河畔,属青铜时代文化遗址  510681      9     -1     12

它标记出了识别到省、市、区的关键位置(index),当然如果是德阳市这种特殊的识别会被标记为-1.

3.高级使用

它还可以从大段文本中批量识别多个地区:

# 公众号: Python 实用宝典
# 2022/06/23

import cpca

long_text = "对一个城市的评价总会包含个人的感情。如果你喜欢一个城市,很有可能是喜欢彼时彼地的自己。"\
    "在广州、香港读过书,工作过,在深圳买过房、短暂生活过,去北京出了几次差。"\
    "想重点比较一下广州、深圳和香港,顺带说一下北京。总的来说,觉得广州舒适、"\
    "香港精致、深圳年轻气氛好、北京大气又粗糙。答主目前选择了广州。"
df = cpca.transform_text_with_addrs(long_text, pos_sensitive=True)
print(df)

效果如下:

(base) G:\push\20220623>python 1.py
          省     市     区 地址  adcode  省_pos  市_pos  区_pos
0       广东省   广州市  None     440100     -1     44     -1
1   香港特别行政区  None  None     810000     47     -1     -1
2       广东省   深圳市  None     440300     -1     58     -1
3       北京市  None  None     110000     71     -1     -1
4       广东省   广州市  None     440100     -1     86     -1
5       广东省   深圳市  None     440300     -1     89     -1
6   香港特别行政区  None  None     810000     92     -1     -1
7       北京市  None  None     110000    100     -1     -1
8       广东省   广州市  None     440100     -1    110     -1
9   香港特别行政区  None  None     810000    115     -1     -1
10      广东省   深圳市  None     440300     -1    120     -1
11      北京市  None  None     110000    128     -1     -1
12      广东省   广州市  None     440100     -1    143     -1

不仅如此,模块中还自带一些简单绘图工具,可以在地图上将上面输出的数据以热力图的形式画出来:

# 公众号: Python 实用宝典
# 2022/06/23

import cpca
from cpca import drawer

long_text = "对一个城市的评价总会包含个人的感情。如果你喜欢一个城市,很有可能是喜欢彼时彼地的自己。"\
    "在广州、香港读过书,工作过,在深圳买过房、短暂生活过,去北京出了几次差。"\
    "想重点比较一下广州、深圳和香港,顺带说一下北京。总的来说,觉得广州舒适、"\
    "香港精致、深圳年轻气氛好、北京大气又粗糙。答主目前选择了广州。"
df = cpca.transform_text_with_addrs(long_text, pos_sensitive=True)
drawer.draw_locations(df[cpca._ADCODE], "df.html")

运行的时候可能会报这个错:

(base) G:\push\20220623>python 1.py
Traceback (most recent call last):
  File "1.py", line 12, in <module>
    drawer.draw_locations(df[cpca._ADCODE], "df.html")
  File "G:\Anaconda3\lib\site-packages\cpca\drawer.py", line 41, in draw_locations
    import folium
ModuleNotFoundError: No module named 'folium'

使用pip安装即可:

pip install folium

然后重新运行代码,会在当前目录下生成 df.html, 双击打开,效果如下:

怎么用,是不是感觉非常方便?以后地点的识别用这个模块就完全够了。

还有更多的细节你可以访问这个项目的Github主页阅读,该项目的README完全中文编写,非常容易阅读:

https://github.com/DQinYuan/chinese_province_city_area_mapper

如果你无法访问GitHub,也可以在Python实用宝典公众号后台回复:cpca 下载完整项目。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

Empyrical 教你一行代码计算风险指标

Empyrical 是一个知名的金融风险指标库。它能够用于计算年平均回报、最大回撤、Alpha值、Beta值、卡尔马率、Omega率、夏普率等。它还被用于zipline和pyfolio,是Quantopian开发的三件套之一。

下面就教你如何使用 Empyrical 这个风险指标计算神器。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install empyrical

2. Empyrical 基本使用

计算最大回撤,你只需要从 empyrical 库中引入 max_drawdown ,将数据作为参数传入计算,一行代码就能实现:

import numpy as np
from empyrical import max_drawdown

returns = np.array([.01, .02, .03, -.4, -.06, -.02])

# 计算最大回撤
max_drawdown(returns)
# -0.4472800000000001

同样地,如果你需要计算alpha和beta指标:

import numpy as np
from empyrical import alpha_beta

returns = np.array([.01, .02, .03, -.4, -.06, -.02])
benchmark_returns = np.array([.02, .02, .03, -.35, -.05, -.01])

# 计算alpha和Beta值
alpha, beta = alpha_beta(returns, benchmark_returns)
print(alpha, beta)
# -0.7960672549836803 1.1243025418474892

如果你想要计算夏普率,同样也是一行代码就能解决,只不过你需要注意这几个参数的意义:

import numpy as np
from empyrical import sharpe_ratio

returns = np.array([.01, .02, .03, -.4, -.06, -.02])

# 计算夏普率
sr = sharpe_ratio(returns, risk_free=0, period='daily', annualization=None)
print(sr)
# -6.7377339531573535

各个参数的意义如下:

参数数据类型意义
returnspandas.Series策略的日回报,非累积。
risk_freeint, float本周期内的无风险利率
periodstr, optional确定回报数据的周期,默认为天。
annualizationint, optional交易日总数(用于计算年化)。如果是daily,则默认为252个交易日。

3.更多的指标

Empyrical 能提供使用的指标非常多,这里就不一一介绍了,基本上用法都和夏普率的计算方法差不多,这里介绍他们的方法和参数。

3.1 omega_ratio

empyrical.omega_ratio(returns, risk_free=0.0, required_return=0.0, annualization=252)
参数数据类型意义
returnspandas.Series策略的日回报,非累积。
risk_freeint, float本周期内的无风险利率
required_returnfloat, optional投资者可接受的最低回报。考虑正收益与负收益的阈值。它会被转为适应本周期回报的值。例如,可接受的最低年回报100会被转为最低0.018
annualizationint, optional交易日总数(用于计算年化)。如果是daily,则默认为252个交易日。

3.2 calmar_ratio

empyrical.calmar_ratio(returns, period='daily', annualization=None)
参数数据类型意义
returnspandas.Series策略的日回报,非累积。
periodstr, optional确定回报数据的周期,默认为天。
annualizationint, optional交易日总数(用于计算年化)。如果是daily,则默认为252个交易日。

3.3 sortino_ratio

empyrical.sortino_ratio(returns, required_return=0, period='daily', annualization=None, _downside_risk=None)
参数数据类型意义
returnspandas.Series策略的日回报,非累积。
required_returnfloat最小投资回报
periodstr, optional确定回报数据的周期,默认为天。
annualizationint, optional交易日总数(用于计算年化)。如果是daily,则默认为252个交易日。
_downside_riskfloat, optional给定输入的下跌风险。如果没有提供则自动计算

更多的指标及其说明,请查看empyrical源代码的stats.py文件,里面还包含了所有指标的计算逻辑,如果你想了解每个指标的计算方法,可以查看这个文件进行学习:

https://github.com/quantopian/empyrical/blob/master/empyrical/stats.py

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

超实用!教你 Python 获取并下载美股数据

yfinance 是一个使用 Yahoo! 获取数据的 Python 第三方模块。它支持获取最细到1分钟级的历史数据及股票基本面数据,是免费获得美股分钟级及以上粒度数据的不二之选。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install yfinance

2.yfinance 基本使用

通过yfinance你可以使用一样命令下载任意美股股票的数据,比如:

import yfinance as yf

# 单股
data = yf.download("AAPL", start="2017-01-01", end="2017-04-30")
#                  Open       High        Low      Close  Adj Close     Volume
# Date
# 2017-01-03  28.950001  29.082500  28.690001  29.037500  27.257641  115127600
# 2017-01-04  28.962500  29.127501  28.937500  29.004999  27.227135   84472400
# 2017-01-05  28.980000  29.215000  28.952499  29.152500  27.365593   88774400
# 2017-01-06  29.195000  29.540001  29.117500  29.477501  27.670671  127007600
# 2017-01-09  29.487499  29.857500  29.485001  29.747499  27.924126  134247600
# ......

# 多股
data = yf.download("SPY AAPL", start="2017-01-01", end="2017-04-30",
                   group_by="ticker")
#                  AAPL                                   ...         SPY
#                  Open       High        Low      Close  ...         Low       Close   Adj Close     Volume
# Date                                                    ...
# 2017-01-03  28.950001  29.082500  28.690001  29.037500  ...  223.880005  225.240005  205.509079   91366500
# 2017-01-04  28.962500  29.127501  28.937500  29.004999  ...  225.610001  226.580002  206.731735   78744400
# 2017-01-05  28.980000  29.215000  28.952499  29.152500  ...  225.479996  226.399994  206.567459   78379000
# 2017-01-06  29.195000  29.540001  29.117500  29.477501  ...  225.899994  227.210007  207.306549   71559900
# ......

默认是获取天级别的数据,如果你需要获取分钟级的,只需要添加interval参数:

import yfinance as yf

# 单股
data = yf.download("AAPL", start="2022-05-18", end="2022-05-23", interval="1m")
print(data)

#                                  Open        High         Low       Close   Adj Close   Volume
# Datetime
# 2022-05-17 12:00:00-04:00  148.000000  148.050003  147.839996  147.865005  147.865005        0
# 2022-05-17 12:01:00-04:00  147.869507  147.919998  147.779999  147.889893  147.889893   123746
# 2022-05-17 12:02:00-04:00  147.889999  147.929993  147.750000  147.907394  147.907394    92847
# 2022-05-17 12:03:00-04:00  147.904999  147.929993  147.785004  147.839996  147.839996    79266
# 2022-05-17 12:04:00-04:00  147.839996  147.895004  147.779999  147.860001  147.860001    58905
# ......

它支持的分钟级参数有:1m,2m,5m,15m,30m,60m,90m等等

此外还支持小时级和天线、周线、月线级别:1h,1d,5d,1wk,1mo,3mo等等

获取到的数据类型就是Dataframe,因此你还可以直接保存为csv文件:

# 公众号:Python 实用宝典
import yfinance as yf

data = yf.download("AAPL", start="2022-05-18", end="2022-05-23", interval="1m")
data.to_csv("aapl_20220518_20220523.csv")
# 保存到本地,命名为 aapl_20220518_20220523.csv

3.通过yfinance获取股票基本数据

如果你需要获取一只股票的基本数据,如市值、市盈率、股息等,你可以通过定义一只股票的Ticker,利用其info属性获取:

# 公众号:Python 实用宝典
import yfinance as yf

aapl = yf.Ticker("aapl")
print(aapl.info)
# {'zip': '95014', 'sector': 'Technology', 'fullTimeEmployees': 154000, 'longBusinessSummary': 'Apple ......

这个字典比较长,这里省略显示了,里面包含了比如市盈率(PE)等信息:

# 公众号:Python 实用宝典
import yfinance as yf

aapl = yf.Ticker("aapl")
aapl.info['forwardPE']
# 20.974085

你还可以获取每次派息数据:

# 公众号:Python 实用宝典
import yfinance as yf

aapl = yf.Ticker("aapl")
print(aapl.dividends)
# Date
# 1987-05-11    0.000536
# 1987-08-10    0.000536
# 1987-11-17    0.000714
# 1988-02-12    0.000714
# 1988-05-16    0.000714
#                 ...
# 2021-05-07    0.220000
# ...             ...

获取资产负债表:

# 公众号:Python 实用宝典
import yfinance as yf

aapl = yf.Ticker("aapl")
print(aapl.balancesheet)
#                              2021-09-25    2020-09-26    2019-09-28    2018-09-29
# Total Liab                 2.879120e+11  2.585490e+11  2.480280e+11  2.585780e+11
# Total Stockholder Equity   6.309000e+10  6.533900e+10  9.048800e+10  1.071470e+11
# Other Current Liab         5.357700e+10  4.786700e+10  4.324200e+10  3.929300e+10
# Total Assets               3.510020e+11  3.238880e+11  3.385160e+11  3.657250e+11
# Common Stock               5.736500e+10  5.077900e+10  4.517400e+10  4.020100e+10
# ......

现金流数据:

# 公众号:Python 实用宝典
import yfinance as yf

aapl = yf.Ticker("aapl")
print(aapl.cashflow)
#                                              2021-09-25    2020-09-26    2019-09-28    2018-09-29
# Investments                               -2.819000e+09  5.335000e+09  5.809300e+10  3.084500e+10
# Change To Liabilities                      1.400200e+10 -1.981000e+09 -2.548000e+09  9.172000e+09
# Total Cashflows From Investing Activities -1.454500e+10 -4.289000e+09  4.589600e+10  1.606600e+10
# ......

新闻数据:

# 公众号:Python 实用宝典
import yfinance as yf

aapl = yf.Ticker("aapl")
print(aapl.news)
# [{'uuid': '476a41c6-c6dc-3050-9b8f-c3777c8485b2', 'title': "Dow Jones Futures Rise After 'Hard' Reality Hits Market; What To Do Now", 'publisher': "Investor's Business Daily", 
# 'link': 'https://finance.yahoo.com/m/476a41c6-c6dc-3050-9b8f-c3777c8485b2/dow-jones-futures-rise-after.html', 
# 'providerPublishTime': 1653305573, 'type': 'STORY'}, {'uuid': '721d466d-5394-3f3c-a9c3-b0920d44c7f3' ......

总之,有了yfinance这个神器,除了高频数据你无法获取之外,其他的美股数据你都能获取得到,有需要的小伙伴可以试试,非常好用。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

教你如何用Python上传日志并监控告警

在我们的日常生活工作中,经常会遇到需要上传日志的场景,比如多台机器运行同一个程序,并且需要记录每台机器程序产生的日志,根据相关关键词告警,或者进行无数据告警,如果自己搭建这套系统需要耗费不少时间,因此如果能使用市面上现成的系统会很方便。

本文将教你如何通过阿里云日志服务搭建一套通过Python上传日志、配置日志告警的监控服务。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install aliyun-log-python-sdk

接下来,登陆阿里云控制台,进入日志应用,通过下面的步骤创建日志Project和Logstore:

点击Python – SDK 写入,再根据你的需要创建Project和Logstore:

随后会进入这个页面,直接点击确定即可:

2.使用阿里云SDK上传Python日志

为了使用阿里云SDK上传日志,我们需要先获取Access Token, 将鼠标移动到右上角头像上点击AccessKey管理:

然后点击创建AccessKey,输入相关验证信息就能获取 accessKeyId 和 accessKey:

编写Python代码,配置AccessKey和你在第一步骤创建的Project及logstore名称:

from aliyun.log import LogClient, PutLogsRequest, LogItem, GetLogsRequest, IndexConfig
import time

# 配置AccessKey、服务入口、Project名称、Logstore名称等相关信息。
# 阿里云访问密钥AccessKey。更多信息,请参见访问密钥。
# 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维。
accessKeyId = "你的AccessKey ID"
accessKey = "你的AccessKey"
# 日志服务的域名。更多信息,请参见服务入口。此处以广州为例,其它地域请根据实际情况填写。
endpoint = "cn-guangzhou.log.aliyuncs.com"

# 创建日志服务Client。
client = LogClient(endpoint, accessKeyId, accessKey)

# Project名称。
project_name = "aliyun-test-project"
#Logstore名称
logstore_name = "aliyun-test-logstore"
# 查询语句。
query = "*| select dev,id from " + logstore_name
# from_time和to_time表示查询日志的时间范围,Unix时间戳格式。
from_time = int(time.time()) - 3600
to_time = time.time() + 3600

然后我们就可以编写Python代码创建索引(日志的索引可以理解为MySQL中的数据库)和插入日志了:

# 向Logstore写入数据。
def put_logs():
    print("ready to put logs for %s" % logstore_name)
    log_group = []
    for i in range(0, 100):
        log_item = LogItem()
        contents = [
            ('dev', 'test_put'),
            ('id', str(i))
        ]
        log_item.set_contents(contents)
        log_group.append(log_item)
    request = PutLogsRequest(project_name, logstore_name, "", "", log_group, compress=False)
    client.put_logs(request)
    print("put logs for %s success " % logstore_name)
    time.sleep(5)

if __name__ == '__main__':
    # 向Logstore写入数据。
    put_logs()

运行程序后出现对应的提示,说明日志上传成功:

python test.py
# ready to put logs for tradingview
# put logs for tradingview success 

进入控制台对应的Project,你会看到刚刚上传的日志已经显示在上面:

3.配置日志告警

日志告警的配置也非常简单,输入你的查询条件,获得输出后点击上方另存为告警:

在查询统计中添加你需要监控并触发告警的条件,比如我设置出现一次该日志的时候触发告警:

效果如下,我这里文本配置得太简单了,你也可以在标注中配置复杂一点的文本:

用起来挺方便的,如果你有类似的多机器日志监控服务,比如分布式模型训练监控、交易服务监控等等,可以考虑使用这个日志服务。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

Pyintervals 解决你的阈值判断问题

Pyintervals 是一个用于数值区间计算的模块,比如我们想要判断一个数值是否处于一个、或者一系列区间范围内,就可以使用Pyintervals模块取缔IF-ELSE语句以达到简化代码的目的。

如果你想一次性生成上千个区间阈值并进行数值区间判断,比如根据数值生成成百上千个分类,那么这个模块就是你的最佳选择。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install pyinterval

2.基本使用

使用Pyinterval做区间判断是非常简单的:

from interval import interval
a = interval[1,5]
# interval([1.0, 5.0])
print(3 in a)
# True

此外,你还可以构建一个多区间:

from interval import interval
a = interval([0, 1], [2, 3], [10, 15])
print(2.5 in a)
# True

interval.hall 方法还可以将多个区间合并,取其最小及最大值为边界:

from interval import interval
a = interval.hull((interval[1, 3], interval[10, 15], interval[16, 2222]))
# interval([1.0, 2222.0])
print(1231 in a)
# True

区间并集计算:

from interval import interval
a = interval.union([interval([1, 3], [4, 6]), interval([2, 5], 9)])
# interval([1.0, 6.0], [9.0])
print(5 in a)
# True
print(8 in a)
# False

3.生成多个阈值区间

如果你在做深度学习训练分类任务,你的分类数量比较多,达到了上百个,请不要傻傻地使用IF-ELSE, 下面教你使用四行代码生成上百个阈值区间。

假设你的值区间分布在0,1之间,每个阈值范围为0.005,并有正负两个方向。下面这4行代码就能非常简单地实现你想要的区间阈值:

from interval import interval
import numpy as np
threshold_list = np.arange(0.0, 1.0, 0.005)
intervals = [interval([threshold_list[i - 1], threshold_list[i]]) for i in range(1, len(threshold_list))]
intervals += [interval([-threshold_list[i], -threshold_list[i - 1]]) for i in range(len(threshold_list) - 1, 0, -1)]
print(len(intervals))
# 398
print(intervals[0], intervals[-1])
# interval([0.0, 0.005]) interval([-0.005, -0.0])

有了这个阈值,区间,你想要画分类就非常简单了,下面是一个简单示例,实际工作中要因不同应用场景改变使用方式。

target = 0.023
class_labels = {}
for index, interval_ in enumerate(intervals):
    if target in interval_:
        class_labels[target] = index

Pyintervals对于正在做大规模分类任务的同学而言是非常好用的模块,建议有需要的朋友可以试一试。其他同学也可以收藏点赞记录一下,说不定未来也会有应用场景呢!

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

程序员延寿指南

原文:https://github.com/geekan/HowToLiveLonger

术语

  • ACM: All-Cause Mortality / 全因死亡率

目标

  • 稳健的活得更久

关键结果

  • 降低66.67%全因死亡率
  • 增加~20年预期寿命
  • 维持多巴胺于中轴

分析

  • 主要参考:对ACM的学术文献相对较多,可以作为主要参考
  • 增加寿命与ACM关系非线性:显然增加寿命与ACM关系是非线性函数,这里假设 DeltaLifeSpan=(1/(1-ACM)-1)*10
  • 变量无法简单叠加:显然各个变量之间并不符合独立同分布假设,变量之间的实际影响也并不明确
  • 存在矛盾观点:所有的证据都有文献/研究对应,但注意到:有些文献之间有显著矛盾的观点(如对于碳水摄入比例的矛盾);有些文献存在较大争议(如认为22点前睡觉会提升43%全因死亡率)
  • 研究仅表达相关:所有文献表明的更多是相关而非因果,在阅读时要考虑文献是否充分证明了因果 —— 如某文献表明了日均>=7000步的人有显著低的全因死亡率。但步数少的人可能包含更多长期病患,如果没有合理的排除这块数据,那此文献调查失真

行动

  • 输入
    • 固体:吃白肉(-3%~-11% ACM)、蔬果为主(-17%~-26% ACM),多吃辣(-23% ACM),多吃坚果(-4%~-27% ACM),少吃蛋黄(否则+7% ACM/0.5颗/天),中量碳水、多吃植物蛋白(-10% ACM)
    • 液体:喝咖啡(-12%~-22% ACM),喝牛奶(-10%~-17% ACM),喝茶(-8%~15% ACM),少喝或不喝甜味饮料(否则每天一杯+7% ACM,+多巴胺),戒酒或每周100g(纯酒精量(g)=饮酒量(ml)×酒精浓度(%)×酒精密度0.8g/ml)内(否则+~50% ACM,无上限)
    • 气体:不吸烟(否则+~50% ACM,-11~-12年寿命)
    • 光照:晒太阳(-~40% ACM)
    • 药物:二甲双胍(糖尿病人相比正常人可以+3年)、复合维生素(-8%癌症风险)、亚精胺(-30%~-60% ACM)、葡萄糖胺(-39% ACM)
  • 输出
    • 运动:每周3次45分钟挥拍运动(-47% ACM)
    • 日常:刷牙(-25% ACM)
    • 睡眠:每天睡7小时全因死亡率最低;且22-24点间最好,早睡+43% ACM,晚睡+15% ACM
  • 上下文
    • 体重:减肥(-54% ACM)

证据

输入

固体
  • 热量限制
    • 怎么看待BBC《进食、断食与长寿》?
      • 限制卡路里动物实验:CR(热量限制,即少吃)延迟了恒河猴的多种疾病发病和死亡率,与CR动物相比,正常喂养的猴子的各种疾病患病风险增加2.9倍,死亡风险增加3.0倍。
  • 综合
    • 最强营养搭配!BMJ:这么吃,心血管疾病和死亡风险更低
      • 通过对这些参与者的数据进行分析,研究人员发现碳水化合物(糖、淀粉和纤维)和蛋白质的摄入与全因死亡率呈非线性关系,而脂肪则与全因死亡率呈线性相关。其中,较高的糖分摄入与全因死亡风险和患心血管疾病的风险较高均有关联,而较高的饱和脂肪酸摄入与全因死亡风险较高有关。
      • 图1:各种营养元素与全因死亡之间的关系
  • 图2:各种营养元素与心血管疾病之间的关系
    • 进一步研究表明,在所有的饮食模式中,全因死亡率风险最低的饮食方式为:10-30g高纤维、14-30%蛋白质、10-25%单不饱和脂肪酸、5%-7%多不饱和脂肪酸以及20%-30%淀粉摄入。
    • 最优能量来源配比:<24%淀粉,15%-17%蛋白质,>15%单不饱和脂肪酸,<15%糖,6%饱和脂肪酸,6%多不饱和脂肪酸,30g+高纤维
液体

气体
  • 吸烟
    • 即使是低强度吸烟,也增加死亡风险!
      • 研究发现:在42 416名男性和86 735名女性(年龄在35-89岁之间,以前没有患病)中,18 985名男性(45%)和18 072名女性(21%)目前吸烟,其中33%的男性吸烟者和39%的女性吸烟者并不每天吸烟。8866名男性(21%)和53 912名女性(62%)从不吸烟。在随访期间,与从不吸烟相比,每天<10支烟或每天≥10支烟的全因死亡率危险比分别为1.17(95%置信区间1.10-1.25)和1.54(1.42-1.67)。无论年龄或性别,危险比相似。与每日吸烟关系最密切的疾病是呼吸道癌症、慢性阻塞性肺病和胃肠道及血管疾病。在招募时已经戒烟的人的死亡率低于现在每天吸烟者。
      • 吸烟者平均减少寿命11-12年
    • 吸烟让人过瘾是什么原理?有节制的吸烟依旧有害吗?
光照
药物
  • 复合维生素
  • 葡萄糖胺
    • 神奇!氨糖降低心血管死亡率65%,与定期运动效果相当
    • 美国西弗吉尼亚大学最新研究发现 氨糖(软骨素) 可以降低心血管死亡率65%,降低总体死亡率39%,效果与坚持定期运动相对
    • 该研究使用1999年至2010年,16,686名成年人的国家健康和营养检查(NHANES)数据,参与者的中位追踪时间为107个月,而其中有648位参与者定期且每服用日500-1000毫克的葡萄糖胺/软骨素一年以上。
  • 亚精胺
    • Science:科学背书!从精液中发现的亚精胺,竟然有着抗衰老、抗癌、保护心血管和神经、改善肥胖和2型糖尿病等逆天神效
    • 亚精胺是最容易从人体肠道吸收的多胺。许多的食物中都含有大量的亚精胺,例如新鲜的青椒、小麦胚芽、花椰菜、西兰花、蘑菇和各种奶酪,尤其在纳豆等大豆制品、香菇和榴莲中含量更高。在本实验中,研究人员选择了829位年龄在45-84岁之间的参与者进行了为期20年的随访,分析了饮食中亚精胺摄入量与人类死亡率之间的潜在关联。
    • 研究发现,女性的亚精胺摄入量高于男性,并且摄入量都会随着年龄的增长而下降。亚精胺的主要来源是全谷物(占13.4%)、苹果和梨(占13.3%)、沙拉(占9.8%)、芽菜(占7.3%)和马铃薯(占6.4%)。研究根据亚精胺摄入量将人群分为三组,低摄入量组(<62.2 µmol / d)、中摄入量组(62.2–79.8 µmol / d)和高摄入量组(> 79.8 µmol / d)。随访期间共记录了341例死亡,其中血管疾病137例,癌症94例,其他原因110例。经计算低中高三组的粗略死亡率分别为40.5%、23.7%和15.1%,这些数据表明亚精胺摄入量与全因死亡率之间的负相关关系显著。随着逐步对年龄、性别和热量的比例进行调整,这种相关关系依然显著。
  • 综合

输出

挥拍运动
走路
刷牙
泡澡
  • 定期洗澡降低心血管疾病发作风险
    • 与每周一至两次泡澡或根本不泡澡相比,每天洗热水澡可以降低28%的心血管疾病总风险,降低26%的中风总风险,脑出血风险下降46%。而浴缸浴的频率与心源性猝死的风险增加无关。
做家务(老年男性)
  • Housework Reduces All-Cause and Cancer Mortality in Chinese Men
    • 72岁之后男性每周做重型家务可以减少29%平均死亡率
    • 重型家务:吸尘、擦地板、拖地、擦洗窗户、洗车、搬动家具、搬煤气罐等等。
    • 轻型家务:掸灰尘、洗碗、手洗衣服、熨烫、晾衣服、做饭、买日用品等等。
睡眠

上下文

情绪
  • 悲观情绪与更高的全因死亡率和心血管疾病死亡率有关,但乐观情绪并不能起到保护作用
    • 在1993-1995年间,一项针对50岁以上澳大利亚人健康的双胞胎研究中包括了生活取向测试(LOT),其中包含乐观和悲观的项目。平均20年后,参与者与来自澳大利亚国家死亡指数的死亡信息相匹配。在2,978名具有很多可用分数的参与者中,有1,068人死亡。生存分析测试了各种乐观因素和悲观情绪分数与任何原因,癌症,心血管疾病或其他已知原因的死亡率之间的关联。年龄调整后的悲观量表上的核心与全因和心血管疾病死亡率相关(每1个标准差单位的危险比,95%置信区间和p值1.134、1.065–1.207、8.85×10 –5和1.196、1.045–1.368、0.0093 ),但不会因癌症死亡。乐观得分与悲观得分之间的相关性很弱(年龄调整后的等级相关系数= − 0.176),但与总死亡率或特定原因死亡率没有显着相关性。反向因果关系(引起悲观情绪的疾病)是不可能的,因为在那种情况下,心血管疾病和癌症都会导致悲观情绪。
贫富
  • JAMA子刊:贫富差距真能影响寿命?这可能是真的!
    • 该研究使用1994-1996年第一次收集的数据,并通过生存模型来分析净资产和长寿之间的关联。结果显示,共收纳5414 名参与者,平均年龄为 46.7岁,包括 2766 名女性。较高的净资产与较低的死亡风险相关。特别是在兄弟姐妹和双胞胎中(n = 2490),在较高的净资产和较低的死亡率之间观察到类似的关联,表明拥有更多财富的兄弟姐妹或双胞胎比拥有更少财富的兄弟姐妹/双胞胎活得更久。
体重
  • JAMA子刊:减肥要趁早,才能有效降低死亡率风险
    • 对体重减轻的死亡率风险评估发现,体重从肥胖减轻到超重的成年人与稳定肥胖人群相比,全因死亡率降低了54%(危险比为0.46),然而从成年初期的超重减轻到中年以前的正常体重的人群的死亡率风险并未降低(风险比为1.12)。
新冠

这个神奇的库,可以将数据平滑化并找到异常点

在处理数据的时候,我们经常会遇到一些非连续的散点时间序列数据:

有些时候,这样的散点数据是不利于我们进行数据的聚类和预测的。因此我们需要把它们平滑化,如下图所示:

将散点都去除,平滑后的效果如下:

​这样的时序数据是不是看起来舒服多了?​此外,使用平滑后的时序数据去做聚类或预测或许有令人惊艳的效果,因为它去除了一些偏差值并细化了数据的分布范围。

如果我们自己开发一个这样的平滑工具,会耗费不少的时间。​因为平滑的技术有很多种,你需要一个个地去研究,找到最合适的技术并编写代码,这是一个非常耗时的过程。平滑技术包括但不限于:

  • 指数平滑
  • 具有各种窗口类型(常数、汉宁、汉明、巴特利特、布莱克曼)的卷积平滑
  • 傅立叶变换的频谱平滑
  • 多项式平滑
  • 各种样条平滑(线性、三次、自然三次)
  • 高斯平滑
  • 二进制平滑

所幸,有大佬已经为我们实现好了时间序列的这些平滑技术,并在GitHub上开源了这份模块的代码——它就是 tsmoothie。

下面就让我们来试一下 tsmoothie.

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install tsmoothie

PS, Tsmoothie仅支持Python 3.6 及以上的版本。

2.Tsmoothie 基本使用

为了尝试Tsmoothie的效果,我们需要生成随机数据:

import numpy as np
import matplotlib.pyplot as plt
from tsmoothie.utils_func import sim_randomwalk
from tsmoothie.smoother import LowessSmoother

# 生成 3 个长度为200的随机数据组
np.random.seed(123)
data = sim_randomwalk(n_series=3, timesteps=200, 
                      process_noise=10, measure_noise=30)

然后使用Tsmoothie执行平滑化:

# 平滑
smoother = LowessSmoother(smooth_fraction=0.1, iterations=1)
smoother.smooth(data)

通过 smoother.smooth_data 你就可以获取平滑后的数据:

print(smoother.smooth_data)
# [[   5.21462928    3.07898076    0.93933646   -1.19847767   -3.32294934 
#     -5.40678762   -7.42425709   -9.36150892  -11.23591897  -13.05271523 
#      .......       .......       .......      .......       .......   ]]

绘制效果图:

# 生成范围区间
low, up = smoother.get_intervals('prediction_interval')

plt.figure(figsize=(18,5))

for i in range(3):
    
    plt.subplot(1,3,i+1)
    plt.plot(smoother.smooth_data[i], linewidth=3, color='blue')
    plt.plot(smoother.data[i], '.k')
    plt.title(f"timeseries {i+1}"); plt.xlabel('time')

    plt.fill_between(range(len(smoother.data[i])), low[i], up[i], alpha=0.3)

3.基于Tsmoothie的极端异常值检测

事实上,基于smoother生成的范围区域,我们可以进行异常值的检测:

可以看到,在蓝色范围以外的点,都属于异常值。我们可以轻易地将这些异常值标红或记录,以便后续的处理。

_low, _up = smoother.get_intervals('sigma_interval', n_sigma=2)
series['low'] = np.hstack([series['low'], _low[:,[-1]]])
series['up'] = np.hstack([series['up'], _up[:,[-1]]])
is_anomaly = np.logical_or(
    series['original'][:,-1] > series['up'][:,-1], 
    series['original'][:,-1] < series['low'][:,-1]
).reshape(-1,1)

假设蓝色范围interval的最大值为up、最小值为low,如果存在 data > up 或 data < low 则表明此数据是异常点。

使用以下代码通过滚动数据点进行平滑化和异常检测,就能保存得到上方的GIF动图。

# https://github.com/cerlymarco/MEDIUM_NoteBook/blob/master/Anomaly_Detection_RealTime/Anomaly_Detection_RealTime.ipynb

import numpy as np
import matplotlib.pyplot as plt
from celluloid import Camera
from collections import defaultdict
from functools import partial
from tqdm import tqdm

from tsmoothie.utils_func import sim_randomwalk, sim_seasonal_data
from tsmoothie.smoother import *


def plot_history(ax, i, is_anomaly, window_len, color='blue', **pltargs):
    
    posrange = np.arange(0,i)
    
    ax.fill_between(posrange[window_len:], 
                    pltargs['low'][1:], pltargs['up'][1:], 
                    color=color, alpha=0.2)
    if is_anomaly:
        ax.scatter(i-1, pltargs['original'][-1], c='red')
    else:
        ax.scatter(i-1, pltargs['original'][-1], c='black')
    ax.scatter(i-1, pltargs['smooth'][-1], c=color)
    
    ax.plot(posrange, pltargs['original'][1:], '.k')
    ax.plot(posrange[window_len:], 
            pltargs['smooth'][1:], color=color, linewidth=3)
    
    if 'ano_id' in pltargs.keys():
        if pltargs['ano_id'].sum()>0:
            not_zeros = pltargs['ano_id'][pltargs['ano_id']!=0] -1
            ax.scatter(not_zeros, pltargs['original'][1:][not_zeros], 
                       c='red', alpha=1.)

np.random.seed(42)

n_series, timesteps = 3, 200

data = sim_randomwalk(n_series=n_series, timesteps=timesteps, 
                      process_noise=10, measure_noise=30)

window_len = 20

fig = plt.figure(figsize=(18,10))
camera = Camera(fig)

axes = [plt.subplot(n_series,1,ax+1) for ax in range(n_series)]
series = defaultdict(partial(np.ndarray, shape=(n_series,1), dtype='float32'))

for i in tqdm(range(timesteps+1), total=(timesteps+1)):
    
    if i>window_len:
    
        smoother = ConvolutionSmoother(window_len=window_len, window_type='ones')
        smoother.smooth(series['original'][:,-window_len:])

        series['smooth'] = np.hstack([series['smooth'], smoother.smooth_data[:,[-1]]]) 

        _low, _up = smoother.get_intervals('sigma_interval', n_sigma=2)
        series['low'] = np.hstack([series['low'], _low[:,[-1]]])
        series['up'] = np.hstack([series['up'], _up[:,[-1]]])

        is_anomaly = np.logical_or(
            series['original'][:,-1] > series['up'][:,-1], 
            series['original'][:,-1] < series['low'][:,-1]
        ).reshape(-1,1)
        
        if is_anomaly.any():
            series['ano_id'] = np.hstack([series['ano_id'], is_anomaly*i]).astype(int)
            
        for s in range(n_series):
            pltargs = {k:v[s,:] for k,v in series.items()}
            plot_history(axes[s], i, is_anomaly[s], window_len, 
                         **pltargs)

        camera.snap()
        
    if i>=timesteps:
        continue
    
    series['original'] = np.hstack([series['original'], data[:,[i]]])

    
print('CREATING GIF...')  # it may take a few seconds
camera._photos = [camera._photos[-1]] + camera._photos
animation = camera.animate()
animation.save('animation1.gif', codec="gif", writer='imagemagick')
plt.close(fig)
print('DONE')

注意,异常点并非都是负面作用,在不同的应用场景下,它们可能代表了不同的意义。

比如在股票中,它或许可以代表着震荡行情中某种趋势反转的信号。

或者在家庭用电量分析中,它可能代表着某个时刻的用电峰值,根据这个峰值我们可以此时此刻开启了什么样的电器。

所以异常点的作用需要根据不同应用场景进行不同的分析,才能找到它真正的价值。

总而言之,Tsmoothie 不仅可以使用多种平滑技术平滑化我们的时序数据,还可以根据平滑结果找出数据中的离群点,是我们做数据分析和研究的一个好帮手,非常有价值。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

教你用Python计算对量化交易至关重要的VWAP指标

成交量加权平均价格 (VWAP) 在金融业中是指特定时间范围内交易价值与交易总数量的比率。它具有三个重要的特点和优势,为交易者提供了对价格趋势的洞察方法。机构和交易者使用 VWAP 来识别买卖区域,并帮助衡量市场情绪。

1.为什么要用VWAP?

VWAP有三个重要的特点:

1. VWAP可以帮助我们了解市场情绪。当证券价格高于VWAP线时,市场对它是乐观看涨的。当价格低于VWAP线时,市场是悲观看跌的。这一点我们可以从下图直观地了解。

2. 许多日内交易者和大型机构投资者以及养老金计划都使用VWAP来作为衡量自己的交易是否会影响市场的重要指标。 比如机构交易者想要卖出自己重要的头寸时,他们的目标是以VWAP或更高的价格卖出。他们会用几种VWAP盘中策略来确定三件事(趋势、谁在影响价格、确定支撑位和压力位)。

3. VWAP及其与证券价格平均值(HLC)的1个标准差可以作为潜在的支撑和阻力,如下图所示。

2 如何用Python计算VWAP

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install pandas

VWAP的计算公式如下:

TP =(最高价+最低价+收盘价)/3

V = 成交量

VWAP = (TP_1 * V_1 + TP_2 * V_2 + TP_n * V_n)/n

例如,如果一只股票以 10 美元交易 1000 股,然后以 11 美元交易 100 股,则最终交易价格为 11 美元;但是,VWAP 将更接近 10:

(1000 * 10 + 100 * 11)/(1000 + 100)) = 10.09

接下来,我们制造一些假数据来准备计算VWAP:

# Get imports
import datetime
import pandas as pd

# Create example dataframe
df = pd.DataFrame(
index=[datetime.datetime(2021,1,1,1),
datetime.datetime(2021,1,1,2),
datetime.datetime(2021,1,1,3),
datetime.datetime(2021,1,1,4)],
data={
  'low':[9,10,11,12],
  'close':[10,11,12,13],
  'high':[11,12,13,14],
  'volume':[1000,750,500,250]
  }
)
df.index.rename('date', inplace=True)

数据如下:

                    low  close  high  volume
date
2021-01-01 01:00:00    9     10    11    1000
2021-01-01 02:00:00   10     11    12     750
2021-01-01 03:00:00   11     12    13     500
2021-01-01 04:00:00   12     13    14     250

VWAP的计算方法如下,这里采用了HLC(open、low、close)的平均值作为基准计算对象:

# Create VWAP function
def vwap(df):
    v = df['volume'].values
    tp = (df['low'] + df['close'] + df['high']).div(3).values
    return df.assign(vwap=(tp * v).cumsum() / v.cumsum())

vwap(df)

计算完成后会在原来的数据上添加一列vwap列:

                     low  close  high  volume       vwap
date
2021-01-01 01:00:00    9     10    11    1000  10.000000
2021-01-01 02:00:00   10     11    12     750  10.428571
2021-01-01 03:00:00   11     12    13     500  10.777778
2021-01-01 04:00:00   12     13    14     250  11.000000

验证一下:

# Verify VWAP
## 以第二行为例
(10*1000 + 11*750) / (1000+750)
10.428571 # 正确

3.VWAP的缺点

没有全能的指标,VWAP也有其自身的缺点。

1.滞后性。和其他的移动平均线一样,VWAP也是一个滞后的指标,而且随着日内交易量的累计,滞后性会越来越严重。

2.仅适用于短期图表,如秒级、分钟级。

4.VWAP 策略

我们已经知道VWAP的运行特点,那么如何利用这些特点进行交易呢?

利用其回调的特点。当股价在一天内显着超过 VWAP 和移动平均线时,它们可能会回调。你可以选择在股价大幅度上涨时卖空股票,也可以选择在回调时等待入场。

Fade策略。这个策略是一个逆势策略,它在强劲势头的运动后采取相反的立场。利用VWAP发的支撑和压力作为其入场和出场的信号。

午后走高策略。这是一个油管老哥(Tim Bohen)观察出来的策略,他发现热门股票早盘走高,并且价格持续保持在vwap上方的股票,午后走高突破的几率非常大。

当然,所有策略都应该被回测后再确定是否有效。以上策略只是一个根据VWAP做交易的思路,你还可以结合其他指标进行策略的开发和回测,有兴趣的同学可以试试看。

本文参考文章:https://analyzingalpha.com/blog/vwap

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

超美!教你用Python拍摄游戏延时摄影

这个时代,随着游戏引擎技术的快速发展,游戏画面越来越精美,许多人迷上了游戏内的角色、场景。

尤其是端游,显卡技术能够支撑精美的游戏画面,最有名的莫过于《地平线》系列游戏。

很多玩家希望拍摄这些精美游戏中的画面,尤其是希望能拍摄到游戏内不同时刻的画面,为了满足这个需求,我们就需要用上延时摄影。游戏内的时间过得比现实世界更快,一个小时内可能你就能经历白天的夜晚的变化,这也为延时摄影提供了很好的环境。

那么究竟怎么在拍摄中实现延时的效果呢?方法大致有两种,最简单的可以先录制视频,然后用后期剪辑软件或者特效软件通过丢帧的方法实现,但这样一来便造成了巨大的浪费。拍几个小时的视频,如果通过丢帧实现延时效果,最后转换为几十分钟的片段,那么被丢掉的帧就要比最后留下的多得多。如果要实现更高速的画面运动,这种浪费无疑将会被更加扩大。

本篇教程介绍第二种方法,定时截图的形式,我们将结合前面Python实用宝典使用过的三个模块——moviepy、win32gui 及 PIL 为大家讲解如何使用Python在游戏中实现延时摄影,我还将教你如何将图片拼接成视频、添加背景音乐一条龙操作。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install moviepy
pip install pypiwin32
pip install pillow

本文所有代码均开源在:https://github.com/Ckend/python-time-lapse-photo 仓库,如果你无法访问GitHub,也可以在Python实用宝典后台回复 延时摄影 下载。

2.定时”拍摄”

为了实现定时拍摄的逻辑,我们需要用到pypiwin32模块和pillow模块,在之前的这篇文章中有介绍过:

超方便的 Python 唤醒窗口自动截图脚本

分为三个步骤:

1. 获得游戏窗口界面

2. 获得游戏界面大小

3. 截图

每隔N秒定时循环执行以上三个步骤,代码如下:

# main.py
# Python实用宝典
# 2022-03-25
import time
import win32gui
from PIL import ImageGrab


def get_window_pos(name):
    name = name
    handle = win32gui.FindWindow(0, name)
    if handle == 0:
        return None
    else:
        return win32gui.GetWindowRect(handle), handle

while True:
    try:
        (x1, y1, x2, y2), handle = get_window_pos('极限竞速:地平线 4')
        win32gui.SetForegroundWindow(handle)
        img_ready = ImageGrab.grab((x1, y1, x2, y2))
        img_ready.save(f"./result/{time.time()}.jpg")
        time.sleep(5)
    except Exception as e:
        print(e)

请注意,”极限竞速:地平线 4″ 要改成你对应拍摄的游戏名称,这样,运行程序后就会自动在result文件夹下定时生成截图:

成功截取你想要的时间段的场景图片后,就可以进行下面的拼接和补充背景音乐部分。

3.拼接延时摄影视频

为了达到延时摄影的效果,我们在这一部分中将使用moviepy模块,拼接所有图片到一个视频中。

当然还要补充背景音乐,代码其实非常简单:

# jointer.py
# Python实用宝典
# 2022-03-25
import os
import moviepy
import moviepy.video.io.ImageSequenceClip
from moviepy.editor import *

def pics2video(frames_dir, video_dst, music, fps=10):
    """
    图片合成MP4

    Args:
        frames_dir (str): 图片目录
        video_dst (str): 目标目录
        fps (int, optional): 帧数. Defaults to 25.
    """
    frames_name = sorted(os.listdir(frames_dir))
    frames_path = [frames_dir+frame_name for frame_name in frames_name]
    clip = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(frames_path, fps=fps)
    
    audio_clip = AudioFileClip(music).volumex(0.5)
    audio = afx.audio_loop( audio_clip, duration=clip.duration)
    final_video = clip.set_audio(audio)

    final_video.write_videofile(video_dst, codec='libx264')

music = '打上花火.mp3'
frames_dir = './result/'
video_dst = 'screenshots.mp4'
pics2video(frames_dir, video_dst, music)

1.将你的音乐放在当前目录下,修改music变量为对应的文件名。

2.调整你想要的fps参数—帧数,这个值越低,画面越顺畅。

运行此文件后就会在当前文件夹下生成 ‘screenshots.mp4’. 这个就是我们的处理结果了,双击打开试试吧。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

有趣好用的Python教程

退出移动版