Python 列表去重的4种方式及性能对比

​列表去重是Python中一种常见的处理方式,任何编程场景都可能会遇到需要列表去重的情况。

列表去重的方式有很多,本文将一一讲解他们,并进行性能的对比。

让我们先制造一些简单的数据,生成0到99的100万个随机数:

from random import randrange

DUPLICATES = [randrange(100) for _ in range(1000000)]

接下来尝试这4种去重方式中最简单最直观的一种方法:

1.新建一个数组,遍历原数组,如果值不在新数组里便加入到新数组中。

# 第一种方式
def easy_way():
    unique = []
    for element in DUPLICATES:
        if element not in unique:
            unique.append(element)
    return unique

进入ipython使用timeit计算其去重耗时:

%timeit easy_way()
# 1.16 s ± 137 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

平均耗时在1.16秒左右,但是在这个例子中我们使用了数组作为存储对象,实际上如果我们改成集合存储去重后的结果,性能会快不少:

def easy_way():
    unique = set()
    for element in DUPLICATES:
        if element not in unique:
            unique.add(element)
    return unique
%timeit easy_way()
# 48.4 ms ± 11.6 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

平均耗时在48毫秒左右,改善明显,这是因为集合和数组的内在数据结构完全不同,集合使用了哈希表,因此速度会比列表快许多,但缺点在于无序。

接下来看看第2种方式:

2.直接对数组进行集合转化,然后再转回数组:

# 第二种去重方式
def fast_way()
    return list(set(DUPLICATES))

耗时:

%timeit fast_way()
# 14.2 ms ± 1.73 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

平均耗时14毫秒,这种去重方式是最快的,但正如前面所说,集合是无序的,将数组转为集合后再转为列表,就失去了原有列表的顺序。

如果现在有保留原数组顺序的需要,那么这个方式是不可取的,怎么办呢?

3.保留原有数组顺序的去重

使用dict.fromkeys()函数,可以保留原有数组的顺序并去重:

def save_order():
    return list(dict.fromkeys(DUPLICATES))

当然,它会比单纯用集合进行去重的方式耗时稍微久一点:

%timeit save_order()
# 39.5 ms ± 8.66 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

平均耗时在39.5毫秒,我认为这是可以接受的耗时,毕竟保留了原数组的顺序。

但是,dict.fromkeys()仅在Python3.6及以上才支持。

如果你是Python3.6以下的版本,那么可能要考虑第四种方式了。

4. Python3.6以下的列表保留顺序去重

在Python3.6以下,其实也存在fromkeys函数,只不过它由collections提供:

from collections import OrderedDict
def save_order_below_py36():
    return list(OrderedDict.fromkeys(DUPLICATES))

耗时:

%timeit save_order_below_py36()
# 71.8 ms ± 16.9 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

平均耗时在72毫秒左右,比 Python3.6 的内置dict.fromkeys()慢一些,这是因为OrderedDict是用纯Python实现的。

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

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

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


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

Pandas 性能优化

Python 用5行代码学机器学习—线性回归

之前Python实用宝典讲过许多关于机器学习的文章,比如:

Python 短文本自动识别个体是否有自杀倾向

[准确率:98%] Python 改进朴素贝叶斯自动分类食品安全新闻 实战教程

准确率94%!Python 机器学习识别微博或推特机器人

Python 机器学习预测泰坦尼克号存活概率

等等…

但是这些文章所使用的模型,读者在第一次阅读的时候可能完全不了解或不会使用。

为了解决这样的问题,我准备使用scikit-learn,给大家介绍一些模型的基础知识,今天就来讲讲线性回归模型。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上噢,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda

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

当然,我更推荐大家用VSCode编辑器,把本文代码Copy下来,在编辑器下方的终端运行命令安装依赖模块,多舒服的一件事啊:Python 编程的最好搭档—VSCode 详细指南。

在终端输入以下命令安装我们所需要的依赖模块:

pip install scikit-learn

看到 Successfully installed xxx 则说明安装成功。

2.简单的训练集

冬天快到了,深圳这几天已经准备开始入冬了。

从生活入手,外界温度对是否穿外套的影响是具有线性关系的:

外界温度是否穿外套
30度
25度
20度
15度
10度

现在,考虑这样的一个问题:如果深圳的温度是12度,我们应不应该穿外套?

这个问题很简单,上述简单的训练集中,我们甚至不需要机器学习就能轻易地得到答案:应该。但如果训练集变得稍显复杂一些呢:

你能看出其中x1, x2, x3和y之间的规律吗?

比较难,但是如果你有足够的数据(比如100个),机器学习能够迅速解决这个问题。

为了方便展示机器学习的威力,我们在这里生产100个这样的训练集(公式为: y=x1 + 2*x2 + 3*x3):

from random import randint
TRAIN_SET_LIMIT = 1000
TRAIN_SET_COUNT = 100

TRAIN_INPUT = list()
TRAIN_OUTPUT = list()
for i in range(TRAIN_SET_COUNT):
    a = randint(0, TRAIN_SET_LIMIT)
    b = randint(0, TRAIN_SET_LIMIT)
    c = randint(0, TRAIN_SET_LIMIT)
    op = a + (2*b) + (3*c)
    TRAIN_INPUT.append([a, b, c])
    TRAIN_OUTPUT.append(op)

然后让线性回归模型使用该训练集(Training Set)进行训练(fit),然后再给定三个参数(Test Data),进行预测(predict),让它得到y值(Prediction),如下图所示。

3.训练和测试

为什么我使用sklearn?因为它真的真的很方便。像这样的训练行为,你只需要3行代码就能搞定:

from sklearn.linear_model import LinearRegression

predictor = LinearRegression(n_jobs=-1)
predictor.fit(X=TRAIN_INPUT, y=TRAIN_OUTPUT)

需要注意线性回归模型(LinearRegression)的参数:

n_jobs:默认为1,表示使用CPU的个数。当-1时,代表使用全部CPU

predictor.fit 即训练模型,X是我们在生成训练集时的TRAIN_INPUT,Y即TRAIN_OUTPUT.

训练完就可以立即进行测试了,调用predict函数即可:

X_TEST = [[10, 20, 30]]
outcome = predictor.predict(X=X_TEST)
coefficients = predictor.coef_

print('Outcome : {}\nCoefficients : {}'.format(outcome, coefficients))

这里的 coefficients 是指系数,即x1, x2, x3.

得到的结果如下:

Outcome : [ 140.]
Coefficients : [ 1. 2. 3.]

验证一下:10 + 20*2 + 30*3 = 140 完全正确。

如何,机器学习模型,用起来其实真的没你想象中的那么难,大部分人很可能只是卡在了安装 scikit-learn 的路上…

顺便给大家留个小练习,将下列欧式距离,使用线性回归模型进行表示。

解决思路和本文的方案其实是类似的,只不过需要变通一下。

解决出来的同学可在后台回复:加群,将代码发给我验证,领取一份小红包并进入Python实用宝典的高质量学习交流群哦。

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

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


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

Python 凯利公式 — 最优投资本金计算

1955年,美国盛行答题积累奖金的电视节目,答题者通过连续答对题目来累计奖金池。而在电视外,庄家针对这个节目开设了答题者能否答对题目的赌盘,吸引了许多赌徒参与下注。

但是,节目在东海岸直播,西海岸则有直播延时,有赌徒便抓住了这个机会,利用延时提前通过电话得到了答题者答题情况,赶在西海岸直播前参与下注,从中套利。

受此启发,贝尔实验室的科学家约翰·拉里·凯利于1956年在《贝尔系统技术期刊》中提出了凯利公式:

“如果通信渠道的输入符号代表偶然事件的结果,在该偶然事件中,可以按照与其概率一致的赔率进行投注,那么一个赌徒就可以利用输入符号给他的信息,使他的钱以指数形式增长。”

论文中他以一个赛马模型提出了凯利公式的雏形:

其中:

f* = 应该放入投注的资本比值
p = 获胜的概率
q = 失败的概率
b = 赔率

举个例子,如果一个赌博你有60%的获胜率(p=0.6, q=0.4),并且赔率是1赔2(b=2),则赌客每次下注的资金是 40% (计算方式:(b*p-q)/b)

当然,当初提出这个公式的凯利其实是为了通信学研究的,并不是很贴近实际投资场景。不过,它有一个变形:

其中:

f* = 应该放入投注的资本比值
p = 获胜的概率
q = 失败的概率
rW = 净利润率
rL = 净损失率

这个公式很关键,因为它使得计算投资利润最大化的本金数额成为可能。比如说,使用我们之前的MACD量化投资策略:

Python 量化投资实战教程(2) —MACD策略

有1万元购买股票,10%的止盈点,10%的止损点,假设针对某只股票每次盈利的概率是7/8,此时rW=0.1, rL=0.1,那么每次交易我们应该投入 f=((7/8)*0.1 – (1/8)*0.1) / 0.1*0.1=7.5%。

也就是说,按照这个策略买股票,每次你只能投入本金的7.5%才能使利润获得最大化。

这个公式用Python来计算也非常简单:

def kelly(p, q, rW, rL):
    """
    计算凯利公式

    Args:
        p (float): 获胜概率
        q (float): 失败概率
        rW (float): 净利润率
        rL (float): 净亏损率

    Returns:
        float: 最大化利润的投资本金占比(%)
    """
    return (p*rW - q*rL)/(rW * rL)

基本就是把公式照搬下来计算。

凯利公式看起来真的很不错,不过,请大家注意了,量化投资中的获胜概率,比如我们上述计算中的盈利概率: 7/8,是基于某只股票的历史数据推测出来的,历史并不代表未来,因为未来是不可知的,我们只能说这只股票,在过去,表现的不错。

所以,模型永远只是一个近似的替代,并不能说明一切,凯利公式也是一样,如果凯利公式告诉你,要放大仓位,你可要三思,万一发生黑天鹅事件,分分钟教你做人,如果你还上了杠杆,那就要上人生最重要的一堂课了。

我们经常会认为凯利公式所针对投注比例是全资产,事实上,我更喜欢将凯利公式所针对的投注比例当做是你可承受损失的资产。

比如你有100万,你能承受10万的损失,那么这10万就能拿来根据凯利公式进行投资,因为这是最保险,能让你心情不那么痛苦的做法。

不要贪,很重要。

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

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

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


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

Python MySQL与Influxdb对比及迁移方案

最近遇到一个新的应用场景:将MySQL存放的时序数据迁移到influxDB中。

这么做的好处在于:

1.Influxdb 读写速度更快。

写数据对比

读数据对比

2.在磁盘占用率上,Influxdb更低。

3.此外,Influxdb的数据可以使用Chronograf进行实时预览

如果以前是将时序数据存放在MySQL,现在为了获取更好的性能和使用更优的可视化工具,我们需要将数据从MySQL迁移到Influxdb中。

这看起来是一个常见场景,经过我一番查阅,发现了 GreatLakesEnergy/Mysql-to-influxdb 这个项目。

可惜的是,作者是基于Python2进行开发的,而且用了几个非常难搭建的模块。想在Python3中重新使用这个项目比较困难,因此我对它进行了改造,改造后的代码如下:

https://github.com/Ckend/Mysql-to-influxdb

如果你有这样的迁移需求,可以继续看下面的详细教程。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上噢,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda

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

当然,我更推荐大家用VSCode编辑器,把本文代码Copy下来,在编辑器下方的终端运行命令安装依赖模块,多舒服的一件事啊:Python 编程的最好搭档—VSCode 详细指南。

下载或Git Clone我修改好的代码:
https://github.com/Ckend/Mysql-to-influxdb

进入该目录后,输入以下命令安装依赖:

pip install -r requirements.txt

看到 Successfully installed xxx 则说明安装成功。

2.迁移配置

在迁移开始前,请在你需要迁移的表里加一个字段 transfered,这个字段用于检测某条数据是否被迁移,默认设为0。一旦迁移完成,这个字段会被设为1.

此外,你需要找到你表里的时间序列字段(time)和分类字段(tag)。

分类字段可能比较难理解,比如说你有一张表记录了每支股票每天的开盘价,那么股票id字段便可理解为一个tag,即下面配置中的siteid_field.

在解压后的目录里新建一个settings.ini, 配置以下信息:

[mysql]
host : mysql host # (本地为127.0.0.1)
port : mysql 端口号 # Default is3306
username : 用户名
password : 密码
db : 数据库
table : 要迁移的表
check_field : 检测字段,默认为0,如果迁移完成,该字段会被设为1
time_field : 时间字段
siteid_field : 分类字段(tag)


[influx]
host : influxdb host # (本地为127.0.0.1)
port : 端口号 # Default:8086
username : 用户名
password : 密码
db : 要迁移进入的数据库

[server]
interval : 5 

配置完上述信息后,执行命令即可开始迁移:

python mysql2influx.py -d -c settings.ini -s

3.迁移是否完成

如何检测迁移任务是否完成,还记得我们刚新增了一个字段 transfered 用于检测某条数据是否被迁移吗?

你只需要在mysql中输入以下sql查询是否还有未被迁移的数据即可:

SELECT count(1) FROM your_table where transfered = 0;

若不为0则说明还有数据未被迁移成功。

不过值得注意的是,迁移脚本里是先进行数据迁移,再回来修改transfered的值。

如果你的数据量非常大,更新MySQL数据有可能会耗时极长,因此查询transfered数量的结果有可能不正确。这点需要特别关注。

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

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

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


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

代号Mallow, 一款普通人用Python耗费两年制作的精美游戏!

代号Mallow,是国外一位叫u/Ancalabro的用户耗费了两年自学成才制成的一款多人本地/在线2D游戏。

这款游戏基于Pygame制作,针对绳索物理、粒子引擎等一系列难题做了针对性的解决方案。从画面效果来看,作者确实做的非常用心。

1.游戏介绍

该游戏拥有以下特点

1.最多同时可在线4名玩家一同游玩(需要转发UDP端口)

2.在线游戏和离线游戏都支持

3.支持玩家对战

4.十二个独特的场景

5.一击必杀的武器机制和“无臂”近战战斗

6.重力反转机制

7.支持三种系统(Mac\Linux\Windows)

不过,尽管这款游戏支持多人游戏,但是需要你对UDP端口进行转发,这会有一定的安全隐患,所以建议大家单人把玩就好了。

键盘控制方法如下:

Z – 菜单选择 / 跳
X – 菜单返回 / 滚动
C – 使用物品
Y – 菜单命令
ENTER – 暂停 / 取消暂停
ESC – 退出程序
箭头 – 移动
减号 – 切换全屏 / 窗口化

2.源代码

如果你很好奇作者是如何用pygame完成这么多功能的,你可以在
https://ancalabro.itch.io/codename-mallow

下载这款游戏的源代码和游戏程序体验一把,相信不会让你失望的。如下图所示,进入网站后拉到留言区上方便会看到下载地址。从上到下分别是windows、Linux、Mac对应的游戏程序,最下方是游戏源代码。

3.好评如潮

Python社区经常会出现许多精心制作的游戏分享,但是像作者这样花了两年时间沉浸在自己的开发世界里制作一款游戏的人并不多见。

社区里大家对这款游戏都赞赏有加,相信这对于作者而言是一个正反馈,让他对制作游戏更有激情。

也希望大家能跟这位作者一样,认真地坚持做一件事情,逐步地将成果分享于众,获得正反馈。

如果能获得超预期的正反馈,就能极大地唤起我们的热情,像催化剂一样,使得我们的“反应”加快。

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

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

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


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

healthchecks, 基于Django监控Cron任务的神器

在运维服务器的时候经常会用到一些Crontab任务。

当你的Crontab中的任务数超过10个的时候,你会发现这些任务管理起来非常困难。

尤其是当这些Cron任务执行失败的时候,比如 Python 实用宝典网 每个月初都会执行一次https证书刷新,有一次协议更新之后,我的脚本失效了三个月,导致证书过期时网站宕机了一天,直到我发现并修复了这个问题。

这就是Crontab任务的一个劣势:没有方便的通知功能。

不过,现在有一个非常方便的开源Django项目能在这些Crontab失效的时候通知你,它就是healthchecks.

它通过一个回调接口判断你的Crontab任务有没有顺利执行。

比如说你有一个python脚本定时执行,healthchecks给定的回调URL是:

http://localhost:8000/ping/880cb4d2

在配置Crontab脚本的时候,就需要这么写:

8 6 * * * python /home/user/test.py && curl -fsS -m 10 --retry 5 -o /dev/null http://localhost:8000/ping/880cb4d2

如果未按时调用回调接口,healthchecks将会通过邮件等通知方式告警。

那么这个“未按时”能否设定宽限呢?比如我有个任务要跑1个小时左右,那么这个任务应该是预计在一个半小时内调用(Ping)回调接口,超过一个半小时如果没有调用回调接口则告警。答案是肯定的。

上图中Period指的是两次Ping之间的时间间隔。下方Grace表示“宽限期”,自从上次Ping以来的时间已超过Period+Grace则会发送告警通知。

如果你用不习惯这种可视化的选择器,它还提供了Crontab表达式给你定义Period和Grace:

真乃神器啊!支持的通知方式如下:

国内用户可能一般只会用到Email和Teams,高级点的用户可能会用到IFTTT的Webhooks和普罗米修斯。总之,按你的爱好来就行。

本地开发

下面教大家如何在本地搭建这个项目:

1. 下载项目

https://github.com/healthchecks/healthchecks

如果你访问不了github,可在【Python 实用宝典】公众号后台回复 healthchecks 下载完整源代码

2.创建虚拟环境

推荐使用Python 3.6+,如果你有conda,那就非常方便了,创建healthchecks虚拟环境:

conda create -n healthchecks python=3.6
activate healthchecks

如果你没有conda,你需要先安装Python3.6,然后使用pip安装virtualenv,在终端输入以下命令创建healthchecks虚拟环境

python3 -m venv healthchecks
source healthchecks/bin/activate

不同系统中命令可能不太一样,遇到问题多利用搜索引擎查询就好了。

3.安装依赖

进入到上述创建好的虚拟环境后,cd进入项目根目录,输入以下命令安装依赖:

pip install -r requirements.txt

4.数据库配置(可选)

该项目默认使用SQLite,这意味着你不需要特殊配置也可照常运转。

如果你需要配置MySQL或PostgreSQL,请阅读hc/local_settings.py.example文件进行配置即可。

5.数据表迁移

Django项目当然少不了这个环节,虚拟环境下,在根目录里运行以下命令进行数据表的迁移:

python manage.py migrate

当然,还要创建超管用户:

python manage.py createsuperuser

6.运行项目

大功告成,输入以下命令即可运行项目:

python manage.py runserver

点击右上角login in登录到超管用户就可以开始使用了。

如果你需要对这个项目进行大规模的改动,建议使用Pycharm作为编程工具,因为使用Pycharm来写Django实在是太爽了,详细可以参考这篇文章:《Pycharm+Django 安装及配置指南》

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

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

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


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

想成为时间管理大师?试试番茄工作法!

番茄工作法,是一种时间管理方法。

没错,掌握了它,或许你能成为时间管理大师。

当然,除非你天赋异禀,想成为罗志祥还是有一定难度的。

番茄工作法有五个基本步骤:

1.决定待完成的任务
2.设定番茄工作法定时器至 n 分钟(通常为25分钟)。
3.持续工作直至定时器提示,记下一个x。
4.短暂休息3-5分钟。
5.每四个x,休息15-30分钟。

四个x被称为一个完整的番茄周期。

番茄工作法的原理有专业的心理学解释(来自wiki):

番茄工作法的关键是规划,追踪,记录,处理,以及可视化。在规划阶段,任务被根据优先级排入”To Do Today” list。 这允许用户预计每个任务的工作量。当每个番茄时结束后,成果会被记录下来以提高参与者的成就感并为未来的自我观察和改进提供原始数据。

番茄时意指每个工作时段的时长。当任务完成后,所有番茄计时器剩下的时间会被用于过度学习。短休息时间可以辅助达到心理学上的同化作用,3-5分钟的短休息间隔开每个番茄工作时段。四个番茄工作时组成一组。一个15-50分钟的长休息间隔开每组作业。

这一时间管理技术的本质目的是减少内生和外在的干扰对意识流的影响。一个单位的番茄工作时不可再细分。当在番茄工作时中被打断的情况下,只可能有两种情况:干扰的活动被推迟(告知 – 协商 – 安排日程 – 回访),或者当前的番茄工作时废弃,必须重新开始。

其中,完成任务后所剩下的时间会被用于过度学习。这里的过度学习指的是达到一次完全正确再现后仍继续识记的记忆,也就是复习。

番茄工作法这么好用,不试试怎么行?实际生活中,我们可以通过电脑/手机/手表来通知自己每个番茄时的完成。下面给大家细数几个好用的APP:

1.Flat Tomato

Flat Tomato应该是我最强烈推荐的,APP做的很用心,操作简洁、人性化,音效、动画看起来非常舒服。支持苹果全家桶的所有设备(iPhone、Mac、iPad、iWatch)。

免费版的Flat Tomato没有任何广告,支持基础的定时器、提醒、打断记录功能,如果你只是为了使用番茄工作法来让自己保持自律,免费版的功能完全够你使用,而且非常简单,没有花里胡哨的功能。

Pro版支持时间线呈现、统计图表以及时间支出类别,这些功能有助于自己回顾时间的利用率,并加以改进时间管理能力。

美中不足的是,它不支持Windows和安卓机器。

更加详细的介绍可以看少数派的推荐:
https://sspai.com/post/34014

2.小番茄

小番茄的强大之处在于,它支持所有设备:

  • Android
  • Android Tablet
  • iPhone
  • iPad
  • Apple Watch
  • Mac
  • Windows
  • Chrome Extension

没错,甚至是Chrome的扩展程序它都支持。

它还能定期发送日报、周报、月报总结自己的工作或学习情况,查看定制目标的完成度。

美中不足的是它缺少打断记录功能,这同时使得它的报表功能相对鸡肋。在功能的使用上也相对而言比较复杂,没那么容易上手。

免费版的功能限制较多,相比于Flat Tomato还是逊色一些。

3.Python写的?

关于番茄工作法相关的软件实在太多了,我也没办法给大家一个个都去试,大家如果觉得以上两个APP还是满足不了自己,可以继续在APP Store或少数派上寻宝。

作为一个技术类公众号,当然要教大家用上Python写的计时器啦!

不过我也不想做重复性的工作,用“Python Pomodoro”关键词一搜,你会发现网上一大堆开源代码。

如果你想在PC机或笔记本上实现我们文首提到的最最最基本的番茄工作法,你只需要安装tomato-clock:

pip install tomato-clock

然后在终端或命令行中输入以下任意一个语句即可开始计时:

$ tomato         # 开启一个25分钟的番茄计时器 + 5分钟休息时间
$ tomato -t      # 开启一个25分钟的番茄计时器
$ tomato -t <n>  # 开启一个<n>分钟的番茄计时器
$ tomato -b      # 休息5分钟
$ tomato -b <n>  # 休息<n>分钟
$ tomato -h      # 帮助

美中不足的是,tomato不支持图表统计。

没关系,我们还有大杀器 pomodoro-cli,它不仅支持计时,还支持图表统计,安装方式:

pip install pomodoro-cli

使用方式,终端输入命令:

pomodoro 60 5 --notif=True --alarm=False

这个语句的意思是,工作时长60分钟,每5分钟休息一次,消息框启用、警告不启用。

每次执行完番茄周期,它都会将数据记录在Home/.pomodoro中,要可视化统计这些信息,可以使用pomostat:

pomostat overall
pomostat week
pomostat thisweek
pomostat lastweek
pomostat week --weekof='2018-01-01'
pomostat stats
pomostat weeks
pomostat today
pomostat yesterday

给大家展示一个pomostat lastweek的效果:

效果还是很不错的。当然,离专业的APP如Flat Tomato还有比较大的差距,但是,这样的一个最简单的功能,或许就够我们用了。

总之,番茄工作法真的是一个让自己保持自律的好工具,强烈推荐大家试一试,严格按照步骤走,很快你就会成为一个高效的人。

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

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

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


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

关于Python3.9,你不可不知的4个新特性

1.词典联合运算符

这是我最喜欢的功能之一,语法非常优美。

在Python3.9,如果你有两个词典,现在可以用这些运算符进行合并和更新。

合并运算符 “|”:

还有update运算符|=,它会更新原始字典:

a = {1: 'a', 2: 'b', 3: 'c'}
b = {4: 'd', 5: 'e'}
a |= b
print(a)
{1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'}

如果我们的词典共享一个key,那么将使用第二个词典中的value:

a = {1: 'a', 2: 'b', 3: 'c', 6: 'in both'}
b = {4: 'd', 5: 'e', 6: 'but different'}
print(a | b)
{1: 'a', 2: 'b', 3: 'c', 6: 'but different', 4: 'd', 5: 'e'}

使用可迭代对象进行字典更新

|=操作符的另一个很酷的特性是能够使用可迭代对象(例如列表或生成器)使用新的键值对更新字典:

a = {'a': 'one', 'b': 'two'}
b = ((i, i**2) for i in range(3))
a |= b
print(a)
{'a': 'one', 'b': 'two', 0: 0, 1: 1, 2: 4}

当然,如果你用|这样做,则会得到TypeError,因为它只能用于dict类型之间的联合。

2.字符串方法

removeprefix()和removesuffix()

str.removeprefix(substring: string) 是一个方法,接收一个substring参数,顾名思义,它将删除字符串对应的substring后缀,如果没有对应的后缀,返回原字符串。

str.removesuffix(substring: string) 是一个方法,接收一个substring参数,它将删除字符串的对应substring前缀,如果没有对应的前缀,返回原字符串。

当然,两个函数执行你可以通过使用string[len(prefix):]前缀和string[:-len(suffix)]后缀来实现。

这些是非常简单的操作,因此也是非常简单的功能,考虑到你可能经常执行这些操作,Python3.9 提供的这两个内置函数应该能让你非常爽。

3.新的数学函数

Python 3.9 的数学模块进行了不少的优化并添加了许多新功能。

比如以前gcd计算最大公因数的函数只能应用于2个数字,这就很蛋疼,我们必须使用 math.gcd(80, math.gcd(64, 152))来处理大于2个数字的情况。

现在 gcd 允许计算任意数量的数字。

import math

# Greatest common divisor
math.gcd(80, 64, 152)
# 8

Math模块中,第一个新增的功能是:

# 最小公倍数
math.lcm(4, 8, 5)
# 40

用于计算最小公倍数:math.lcm,与gcd一样,它允许可变数量的参数。

4.新解析器

这一个更改你可能看不见、摸不着,但它可能改变Python的未来。

以前Python使用 LL(1) 解析器,现在Python开始使用 PEG 解析器,官方认为,这个更改会使得他们更加方便地构建新功能。

因此,请期待Python 3.10,Python团队或许能给我们带来更多的惊喜!

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

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

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


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

Python 最好用的8个VS Code扩展

1. Python extension for Visual Studio Code

这个扩展是由微软官方提供的,支持但不仅限于以下功能:

  • 通过Pylint或Flake8支持代码检查
  • 在VS Code编辑器中调试代码
  • IntelliSense支持自动完成,代码导航和格式化。
  • 支持Jupyter Notebook,Pytest和Unittest
  • 在编辑器中轻松切换Python环境

2.Python Preview

这个插件很牛皮,能够实时可视化你的代码结果。

不仅如此,还能为VSCode切换各种主题皮肤。

3.Sort lines

这个扩展很有意思,可以给你按字母大小排序(升序、降序),也可以进行排序+去重。而且还能将所有文本打乱顺序。

做短文本分类的训练,清洗数据集的时候,这个工具大有用处。

4.Git Graph

这玩意可是Git神器,堪比Pycharm内的Git管理器。

通过这个扩展,可以清楚地看见当前分支的commit记录和变化,可以通过按钮的方式轻易地创建、切换分支、cherry pick、merge等操作。

对比分支、查看未提交的修改……还有许多可定制的扩展设置。

5.Python Snippets

很多时候,我们用到的代码片段都是类似的,比如for循环、try/catch等等,现在有了这个工具,我们只需要输入命令生成代码片段,然后再进行微调,就能完成功能的开发。

此外,有些时候我们可能会忘记某些内置函数的用法,这个工具也能给你提供示例代码做参考,而不用你再去搜索引擎搜索示例,实在非常方便。

6.Better Comments

这是一个让你能更好地编写注释的工具,它能根据关键词用不同的颜色高亮代码片段。支持以下类型的高亮:

1. 感叹号 “!” 代码警告。
2. 问号“?”代表存留疑问。
3. TODO 代码未来将要进行的操作。
4. @param 参数

此外,它还支持在设置中自定义需要高亮句子的首部关键词。

7.autoDocstring

这个扩展我应该已经推荐了好多次,能够自动生成函数的注释格式,通过tab键快速切换填充块编写相应的注释。

8.Python Indent

你有没有觉得VSCode里对Python的自动缩进有点不准确?甚至可以用“丑”来形容。每次我都喜欢强行矫正VSCode给我做的自动缩进。

经过一番查阅,我终于找到了能纠正VSCode缩进错误的扩展,它就是Python Indent,看看下面的示例,相信你也会安装它。

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

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

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


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

A股回测“孕线”策略 — Python 量化投资实战教程(8)

此图像的alt属性为空;文件名为2020090716234615.png

上一篇文章《Python 量化投资实战教程(7)—孕线真的有用吗?》中我们讲到了孕线的形态和其基本的量化规则。

此图像的alt属性为空;文件名为2020081916264349.jpg

不过,当时只是基于一支股票对这个策略进行回测,数据量过少,其结果并不具有参考性。

今天,我们将在A股中抽取1000只股票,计算这些股票在2010年1月1日至2020年5月10日采用孕线策略的收益率。

本文完整源代码和数据均在开源代码仓库中:
https://github.com/Ckend/pythondict-quant

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上噢,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda

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

当然,我更推荐大家用VSCode编辑器,把本文代码Copy下来,在编辑器下方的终端运行命令安装依赖模块,多舒服的一件事啊:Python 编程的最好搭档—VSCode 详细指南。

在终端输入以下命令安装我们所需要的依赖模块:

pip install backtrader
pip install numpy
pip install matplotlib

看到 Successfully installed xxx 则说明安装成功。

2.策略

买入卖出策略与上篇文章一致:

买入:符合孕线形态时,买入。

卖出:涨10%或跌10%。

此图像的alt属性为空;文件名为2020081916264349.jpg

策略核心代码如下:

    # Python 实用宝典
    def next(self):
        self.log("Close, %.2f" % self.dataclose[0])
        if self.order:
            return
        if not self.position:
            # condition1 = self.sma20[0] > self.dataclose[0]
            if self.dataclose[-1] < self.dataopen[-1]:
                harami = (
                    self.datahigh[0] < self.dataopen[-1]
                    and self.datalow[0] > self.dataclose[-1]
                )
            else:
                harami = (
                    self.datahigh[0] < self.dataclose[-1]
                    and self.datalow[0] > self.dataopen[-1]
                )

            if harami:
                self.log("BUY CREATE, %.2f" % self.dataclose[0])
                self.order = self.buy()

        else:
            condition = (self.dataclose[0] - self.bar_executed_close) / self.dataclose[0]
            if condition > 0.1 or condition < -0.1:
                self.log("SELL CREATE, %.2f" % self.dataclose[0])
                self.order = self.sell()

除此之外,在交易完成时要记录利润率:

    def notify_order(self, order):
        if order.status in [order.Submitted, order.Accepted]:
            return
        if order.status in [order.Completed]:
            if order.isbuy():
                self.log(
                    "BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f"
                    % (order.executed.price, order.executed.value, order.executed.comm)
                )

                self.buyprice = order.executed.price
                self.buycomm = order.executed.comm
                self.bar_executed_close = self.dataclose[0]
            else:
                self.log(
                    "SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f"
                    % (order.executed.price, order.executed.value, order.executed.comm)
                )
                temp = float(order.executed.price - self.buyprice)/float(self.buyprice)
                self.params.profits.append(temp)

            self.bar_executed = len(self)

        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            self.log("Order Canceled/Margin/Rejected")

        self.order = None

最后,分析每支股票的利润率,求得平均值并绘图:

# 计算
pos = []
neg = []
for data in result:
    res = np.mean(result[data])
    if res > 0:
        pos.append(res)
    else:
        neg.append(res)
print(f"正收益数量: {len(pos)}, 负收益数量:{len(neg)}")

plt.hist(pos, facecolor="red", edgecolor="black", alpha=0.7)
plt.hist(neg, facecolor="green", edgecolor="black", alpha=0.7)
plt.show()

最终算得正收益数量:493,负收益数量:507,利润分布图如下:

3.总结

针对A股1000支股票10年运行轨迹的回测结果显示,孕线策略收益可能性略低于50%,并不是一个靠谱的通用策略。

也许该策略特别符合某些股票,但是大家请注意,这样的“符合”是基于小样本概率的,这样想你就明白了:【抛五次硬币,五次都朝上的概率是不小的】,因此三千只股票中出现几只这样的股票也非常正常。

不过,许多策略都不能单独使用,我们这个例子中也只是做了一种最简单的回测,如果你有兴趣,可以改造我们的代码,将你自己的想法加入到该策略中,并尝试回测,看看效果如何。

欢迎在公众号后台回复:加群,回答相应红字验证信息,进入互助群交流。

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

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


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

有趣好用的Python教程