所有由Python实用宝典发布的文章

Sweetviz 让你三行代码实现数据分析

Sweetviz是一个开源Python库,它只需三行代码就可以生成漂亮的高精度可视化效果来启动EDA(探索性数据分析)。输出一个HTML。

如上图所示,它不仅能根据性别、年龄等不同栏目纵向分析数据,还能对每个栏目做众数、最大值、最小值等横向对比。

所有输入的数值、文本信息都会被自动检测,并进行数据分析、可视化和对比,最后自动帮你进行总结,是一个探索性数据分析的好帮手。

1.准备

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

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

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

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

pip install sweetviz

2.sweetviz 基本用法

sweetviz 使用的原理是,使用一行代码,生成一个数据报告的对象(其中,my_dataframe是pandas中的DataFrame,一种表格型数据结构):

import pandas as pd
import sweetviz as sv

# 读取数据
my_dataframe = pd.read_csv('../ImpartData/iris.csv')
# 分析数据
my_report = sv.analyze(my_dataframe)
# 生成报告
my_report.show_html()

执行完成后,会在当前文件夹下生成一个HTML的报告文件

双击这个html,你就能看到精美的分析报告了:

其中,分析数据有三种函数可以用,除了上面提到的analyze函数,还有 compare 和 compare_intra 函数。

首先是analyze函数:

analyze(source: Union[pd.DataFrame, Tuple[pd.DataFrame, str]],
            target_feat: str = None,
            feat_cfg: FeatureConfig = None,
            pairwise_analysis: str = 'auto')

可见其有以下4个参数可以配置:

  • source:以pandas中的DataFrame数据结构作为分析对象。
  • target_feat:需要被标记为目标对象的字符串。
  • feat_cfg:需要被跳过、或是需要被强制转换为某种数据类型的特征。
  • pairwise_analysis:相关性分析可能需要花费较长时间。如果超过了你的忍受范围,就需要设置这个参数为on或者off,以判断是否需要分析数据相关性。

compare()丨两个数据集比较

my_report = sv.compare([my_dataframe, "Training Data"], [test_df, "Test Data"], "Survived", feature_config)

要比较两个数据集,只需使用该 compare() 函数。它的参数与 analyze() 相同,只是插入了第二个参数来覆盖比较数据帧。建议使用 [dataframe, “name”] 参数格式以更好地区分基础数据帧和比较数据帧。(例如 [my_df, "Train"] 比 my_df 更好)

compare_intra()丨数据集栏目比较

my_report = sv.compare_intra(my_dataframe, my_dataframe["Sex"] == "male", ["Male", "Female"], feature_config)

想要对数据集中某个栏目下的参数进行分析,就采用这个函数进行。
例如,如果需要比较“性别”栏目下的“男性”和“女性”,就可以采用这个函数。

3.调整报告布局

一旦你创建了你的报告对象,只需将它传递给两个show函数中的一个:

1. show_html():

show_html(  filepath='SWEETVIZ_REPORT.html', 
            open_browser=True, 
            layout='widescreen', 
            scale=None)

show_html(…)将在当前文件路径中创建并保存 HTML 报告。有以下参数:

  • layout (布局):无论是'widescreen''vertical'。当鼠标移过每个功能时,宽屏布局会在屏幕右侧显示详细信息。新的(从 2.0 开始)垂直布局在水平方向上更加紧凑,并且可以在单击时扩展每个细节区域。
  • scale:使用浮点数(scale= 0.8None)来缩放整个报告。
  • open_browser:启用 Web 浏览器的自动打开以显示报告。如果不需要,可以在此处禁用它。

2.show_notebook():

show_notebook(  w=None, 
                h=None, 
                scale=None,
                layout='widescreen',
                filepath=None)

它将嵌入一个 IFRAME 元素,在notebook中显示报告(例如 Jupyter、Google Colab 等)。

请注意,由于Notebook通常是一个更受限制的环境,因此使用自定义宽度/高度/比例值 ( whscale) 可能是个好主意。选项是:

  • w(宽度):设置报告输出窗口的宽度。可以是百分比字符串 ( w="100%") 或像素 (w=900)。
  • h(高度):设置报告输出窗口的高度。可以是像素数 ( h=700) 或将窗口拉伸到与所有特征 ( h="Full")一样高。
  • scale:与上面的 show_html 相同。
  • layout:与上面的 show_html 相同。
  • scale:与上面的 show_html 相同。
  • filepath:可选的输出 HTML 报告。

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

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

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

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

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

Lean — 优秀好用的开源量化交易平台

Lean 是 QuantConnect 开源的一款非常强大的开源量化交易平台,可以回测或运行Python或者C#写的策略,并内置了上百个C#和Python写的策略算法在代码仓库中。

这个开源算法交易引擎,专为轻松地进行策略研究、回测和实时交易而构建。它集成了常见的数据提供商和券商,因此可以快速部署算法交易策略。

LEAN Engine 的核心是用 C# 编写的;但它可以在 Linux、Mac 和 Windows 操作系统上无缝运行。它支持用 Python 3.6 或 C# 编写的算法。

引擎分为许多模块化部分,可以在不接触其他文件的情况下对某个模块进行扩展。

最重要的几个模块是:

  • 结果处理(IResultHandler)处理来自算法交易引擎的所有消息。决定应该发送什么,以及消息应该去哪里。结果处理系统可以将消息发送到本地 GUI 或 Web 界面。
  • 数据源(IDataFeed)连接并下载算法交易引擎所需的数据。从磁盘文件中读取文件进行回测;实时交易则连接到一个流并生成数据对象。
  • 事务处理(ITransactionHandler)处理新的订单请求;要么使用算法提供的模拟模型,要么使用实际券商。
  • 实时事件管理(IRealtimeHandler)生成实时事件 – 例如一天结束的事件。触发对实时事件处理程序的回调。
  • 算法状态设置(ISetupHandler)配置算法资金、投资组合和请求的数据。初始化所需的所有状态参数。

这些都可以从 Launcher 项目中的 config.json 文件进行配置。

1. Leon 安装教程

由于Leon是基于C#开发的,因此我推荐使用Visual Studio进行开发。

1、克隆项目。从 https://github.com/QuantConnect/Lean 克隆项目到本地(如果你网络不通可在公众号后台回复 Lean 下载)。

2、使用 Visual Studio 打开项目中的 QuantConnect.Lean.sln

3、点击 生成 – 生成解决方案

4、点击 F5 则可以运行程序。

如果你在生成解决方案的过程中遇到了类似于如下的错误:

请在工具 – NuGet包管理器 – 程序包管理器设置 中 添加如下的源, 名字任取,链接对了就行: https://api.nuget.org/v3/index.json

2. 回测 Lean 内置的C#策略

Lean 中比较有意思的一点是,其所有C#策略算法都位于 QuantConnect.Algorithm.CSharp 中,所有的Python策略算法都位于 QuantConnect.Algorithm.Python 中:

如果你想回测C#的策略,你只需要修改 QuantConnect.Lean.Launcher 中的 config.json,将 QuantConnect.Algorithm.CSharp 中对应策略名称,修改到 algorithm-type-name 字段对应的值中,如图所示:

然后按 F5 运行程序,回测开始,此时会弹出一个cmd窗口,里面有本次回测的统计数据:

3. 回测 Lean 内置的 Python策略

如果你想要回测内置的Python策略,我们需要先指定Lean使用的Python环境位置:

1.打开系统变量(我的电脑-右键属性-高级系统设置->环境变量->系统变量)

2.点击新建变量,name为 PYTHONNET_PYDLL;value则为你的Python环境的dll文件所在文件夹,如我的为 G:\Anaconda3\python36.dll

3.在此Python环境中安装Lean的依赖:

pip install pandas
pip install wrapt==1.11.2

然后在项目的 config.json 中需要多改几个配置:

然后按F5进行回测,效果如下:

这些统计指标令人眼花缭乱,对于股票的回测我们只要重点关注这些即可:

  • Total Trades: 总交易量
  • Average Win: 平均盈利率
  • Average Loss: 平均亏损率
  • Compounding Annual Return: 复合年回报率
  • Drawdown: 最大回撤率
  • Expectancy: 期望值
  • Net Profit: 净利润
  • Sharpe Ratio: 夏普比率
  • Probabilistic Sharpe Ratio: 概率性夏普比率
  • Loss Rate: 失败率
  • Win Rate: 胜率
  • Profit-Loss Ratio: 盈亏比
  • Alpha: Alpha值
  • Beta: Beta值
  • Total Fees: 总手续费

其他的,按需关注即可。

4. Lean 策略是怎么写的?

开始之前,让我们先学习下 Lean 内置策略的写法:

from AlgorithmImports import *


class MACDTrendAlgorithm(QCAlgorithm):

    def Initialize(self):
        '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''

        self.SetStartDate(2004, 1, 1)    #Set Start Date
        self.SetEndDate(2015, 1, 1)      #Set End Date
        self.SetCash(100000)             #Set Strategy Cash
        # Find more symbols here: http://quantconnect.com/data
        self.AddEquity("SPY", Resolution.Daily)

        # define our daily macd(12,26) with a 9 day signal
        self.__macd = self.MACD("SPY", 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)
        self.__previous = datetime.min
        self.PlotIndicator("MACD", True, self.__macd, self.__macd.Signal)
        self.PlotIndicator("SPY", self.__macd.Fast, self.__macd.Slow)


    def OnData(self, data):
        '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.'''
        # wait for our macd to fully initialize
        if not self.__macd.IsReady: return

        # only once per day
        if self.__previous.date() == self.Time.date(): return

        # define a small tolerance on our checks to avoid bouncing
        tolerance = 0.0025

        holdings = self.Portfolio["SPY"].Quantity

        signalDeltaPercent = (self.__macd.Current.Value - self.__macd.Signal.Current.Value)/self.__macd.Fast.Current.Value

        # if our macd is greater than our signal, then let's go long
        if holdings <= 0 and signalDeltaPercent > tolerance:  # 0.01%
            # longterm says buy as well
            self.SetHoldings("SPY", 1.0)

        # of our macd is less than our signal, then let's go short
        elif holdings >= 0 and signalDeltaPercent < -tolerance:
            self.Liquidate("SPY")


        self.__previous = self.Time

可以看到,其实它和Backtrader的写法相差无几,Initialize 函数设置基本的回测参数,如:

  • self.SetStartDate: 回测起始时间
  • self.SetEndDate: 回测结束时间
  • self.setCash: 回测资金
  • self.AddEquity: 回测对象(Resolution.Daily 是指按日回测)
  • self.PlotIndicator: 绘图时添加指标

而 onData 函数则会在每个数据点上做操作,如果是日线,则每天的数据都会流入到这个函数并运行一遍。因此 onData 就是算法分析的主逻辑。

在这里,你可以检查需要的指标是否已经准备完毕,因为可能存在一些滞后性指标在回测刚开始的时候并没有对应的值;此外,在日线的情况下,你还可以检测上一个数据点是不是和这个点在同一天上,如果是的话则不作任何操作返回:

if not self.__macd.IsReady: return
if self.__previous.date() == self.Time.date(): return

然后就是核心的买入卖出逻辑:

tolerance = 0.0025

holdings = self.Portfolio["SPY"].Quantity

signalDeltaPercent = (self.__macd.Current.Value - self.__macd.Signal.Current.Value)/self.__macd.Fast.Current.Value

# if our macd is greater than our signal, then let's go long
if holdings <= 0 and signalDeltaPercent > tolerance:  # 0.01%
    # longterm says buy as well
    self.SetHoldings("SPY", 1.0)

# of our macd is less than our signal, then let's go short
elif holdings >= 0 and signalDeltaPercent < -tolerance:
    self.Liquidate("SPY")
    
self.__previous = self.Time

如果我持仓的股数<=0, 且信号值大于我设定的阈值,则将我资产的1%买入这只股票。这里和backtrader最大的不同,买入是以资产的百分比为单位的动态买入。当然,你也可以使用限定数量的买入方式:

self.LimitOrder("IBM", 100, self.Securities["IBM"].Price)

如果持仓股市>=0, 且触发卖出信号,则进行清仓操作:

elif holdings >= 0 and signalDeltaPercent < -tolerance:
    self.Liquidate("SPY")

如果你不希望全部清仓,也可以使用 SetHoldings 来调整仓位。

可以看到,Lean相对于Backtrader有更灵活的仓位管理方式,甚至能够进行自动仓位调整、构建投资组合、实时交易等等。而且针对一些比较复杂的策略,你还可以用C#而不是Python来编写以提高运行速度。

综上所述,Lean是一个非常值得深入学习的量化交易平台,有兴趣的同学可以在他们官网学习到更多的内容:

https://www.quantconnect.com/docs

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

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

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

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

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

Box 为你的字典添加点符号访问特性

正常情况下,我们想访问字典中的某个值,都是通过中括号访问,比如:

test_dict = {"test": {"imdb stars": 6.7, "length": 104}}

print(test_dict["test"]["imdb stars"])
# 104

而通过Box模块,我们可以扩展字典功能,使用点符号访问元素:

from box import Box

movie_box = Box({ "Robin Hood: Men in Tights": { "imdb stars": 6.7, "length": 104 } })

movie_box.Robin_Hood_Men_in_Tights.imdb_stars

# 6.7

另外,可以看到默认情况下转换后,字典键值中的空格被转化为了下划线。

下面具体介绍 Box 模块的使用方法。

1.准备

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

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

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

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

pip install --upgrade python-box[all]

2.基本使用

我们可以像文章开头那样传入一个字典给 Box,生成一个Box对象;也可以直接使用参数赋值的方式生成一个Box对象:

from box import Box

my_box = Box(funny_movie='Hudson Hawk', best_movie='Kung Fu Panda')
my_box.funny_movie
# 'Hudson Hawk'

请记住,任何情况下,你往Box对象里添加字典或是数组,这些字典或数组都会被转变为Box对象:

my_box = Box({"team": {"red": {"leader": "Sarge", "members": []}}})
print(my_box.team.red.leader)
# Sarge

my_box.team.blue = {"leader": "Church", "members": []} 
print(repr(my_box.team.blue))
# <Box: {'leader': 'Church', 'members': []}>

访问列表中的 Box 对象也非常轻松:

my_box.team.red.members = [
    {"name": "Grif", "rank": "Minor Junior Private Negative First Class"},
    {"name": "Dick Simmons", "rank": "Captain"}
]

print(my_box.team.red.members[0].name)
# Grif

局限性

请注意,字典中有些默认方法,如:clear, copy, fromkeys, get, items, keys, pop, popitem, setdefault, to_dict, update, merge_update, values,当你的键值和这些方法名称冲突时,你无法使用点符号访问它们。

不过冲突时,你依然可以使用传统的字典取值访问它们,例如:

my_box['keys']

合并

要合并两个Box对象,你只需要通过 merge_update 方法:

from box import Box

box_1 = Box(val={'important_key': 1}) 
box_2 = Box(val={'less_important_key': 2})

box_1.merge_update(box_2)

print(box_1)
# {'val': {'important_key': 1, 'less_important_key': 2}}

当然,你也可以用传统的 update 方法:

from box import Box

box_1 = Box(val={'important_key': 1}) 
box_2 = Box(val={'less_important_key': 2})

box_1.update(box_2)

print(box_1)
# {'val': {'less_important_key': 2}}

转换为原始列表/字典

如果你需要把一个 Box 对象的字典转化为原始字典,.to_dict() 方法就可以帮你实现:

from box import Box

box_1 = Box(val={'important_key': 1}) 

print(box_1)
# {'val': {'less_important_key': 2}}
print(type(box_1))
# <class 'box.box.Box'>
print(type(box_1.to_dict()))
# <class 'dict'>

如果你需要把一个 Box 对象的列表转化为原始列表,你可以使用 .to_list() 方法:

from box import BoxList

my_boxlist = BoxList({'item': x} for x in range(10))
#  <BoxList: [<Box: {'item': 0}>, <Box: {'item': 1}>, ...

my_boxlist[5].item
# 5

print(type(my_boxlist.to_list()))
# <class 'list'>

3.导入导出功能

Box对象有一个很方便的功能,就是能够轻松地将Box对象导出为Json/yaml/csv/msgpack文件:

from box import BoxList

my_boxlist = BoxList({'item': x} for x in range(10))
#  <BoxList: [<Box: {'item': 0}>, <Box: {'item': 1}>, ...

my_boxlist.to_json(filename="test.json")
# 在当前文件夹下生成一个 test.json 文件

此外,还能接受 Json/yaml/csv/msgpack 文件导入:

new_box = Box.from_json(filename="films.json")

各种类型的文件对应的方法如下:

转换器方法描述
to_dict递归地将所有 Box(和 BoxList)对象转换回字典(和列表)
to_json将 Box 对象另存为 JSON 字符串或使用filename参数写入文件
to_yaml将 Box 对象另存为 YAML 字符串或使用filename参数写入文件
to_msgpack将 Box 对象另存为 msgpack 字节或使用filename参数写入文件
to_toml*将 Box 对象另存为 TOML 字符串或使用filename参数写入文件
to_csv**将 BoxList 对象另存为 CSV 字符串或使用filename参数写入文件
from_jsonClassmethod,从一个 JSON 文件或字符串创建一个 Box 对象(所有 Box 参数都可以传递)
from_yaml类方法,从 YAML 文件或字符串创建一个 Box 对象(所有 Box 参数都可以传递)
from_msgpackClassmethod,从msgpack文件或字节创建一个Box对象(所有Box参数都可以传递)
from_toml*Classmethod,从TOML文件或字符串创建一个Box对象(所有Box参数都可以传递)
from_csv**Classmethod,从一个CSV文件或字符串创建一个BoxList对象(可以传递所有BoxList参数)

* 不适用于 BoxList,仅适用于 Box ** 不适用于 Box,仅适用于 BoxList。

还有更多的特性,大家可以参考 Box 模块官方WIki:

https://github.com/cdgriffith/Box/wiki

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

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

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

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

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

Delorean 优秀的Python时间格式转换工具

DeLorean是一个Python的第三方模块,基于 pytz 和 dateutil 开发的,用于处理Python中日期时间的格式转换。

由于时间转换是一个足够微妙的问题,DeLorean希望为移位、操作和生成日期时间提供一种更干净、更省事的解决方案。比如,实例化字符串形式的时间对象,Delorean只需要 parse 指定字符串,不需要声明其格式就可以进行转换。

至于 Delorean 这个模块名称的由来,Delorean 是电影《回到未来》里的那辆极为炫酷的鸥翼汽车,采用这部电影里的非常具有代表性的汽车的名字作为库名,作者估计也是想表达使用这个库能让你在时空里任意遨游,没有掣肘。

1.准备

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

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

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

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

pip install Delorean

2.Delorean 基础使用

轻松获取当前时间:

from delorean import Delorean

d = Delorean()
print(d)
# Delorean(datetime=datetime.datetime(2021, 10, 6, 9, 5, 57, 611589), timezone='UTC')

将datetime格式的时间转化为Delorean:

import datetime
from delorean import Delorean

d = Delorean()
print(d)
d = Delorean(datetime=datetime.datetime(2018, 5, 10, 8, 52, 23, 560811), timezone='UTC')
# 这里默认的是UTC时间
print(d)
# Delorean(datetime=datetime.datetime(2021, 10, 6, 9, 5, 57, 611589), timezone='UTC')
# Delorean(datetime=datetime.datetime(2018, 5, 10, 8, 52, 23, 560811), timezone='UTC')

转换为国内时区:

import datetime
from delorean import Delorean

d = Delorean(datetime=datetime.datetime(2018, 5, 10, 8, 52, 23, 560811), timezone='UTC')
d = d.shift("Asia/Shanghai")
print(d)
# Delorean(datetime=datetime.datetime(2018, 5, 10, 16, 52, 23, 560811), timezone='Asia/Shanghai')

输出为 datetime、date 也不在话下:

import datetime
from delorean import Delorean

d = Delorean(datetime=datetime.datetime(2018, 5, 10, 8, 52, 23, 560811), timezone='UTC')
d = d.shift("Asia/Shanghai")
print(d.datetime)
print(d.date)
# 2018-05-10 16:52:23.560811+08:00
# 2018-05-10

查看无时区时间及时间戳:

import datetime
from delorean import Delorean

d = Delorean(datetime=datetime.datetime(2018, 5, 10, 8, 52, 23, 560811), timezone='UTC')
d = d.shift("Asia/Shanghai")
print(d.epoch)
print(d.naive)
# 1525942343.560811
# 2018-05-10 08:52:23.560811

用unix时间戳初始化Delorean:

from delorean import epoch
d = epoch(1357971038.102223).shift("Asia/Shanghai")
print(d)
# Delorean(datetime=datetime.datetime(2013, 1, 12, 14, 10, 38, 102223), timezone='Asia/Shanghai')

Delorean支持timedelta的时间加减法。Delorean可以使用timedelta进行加减,得到一个Delorean对象:

import datetime
from delorean import Delorean

d = Delorean(datetime=datetime.datetime(2018, 5, 10, 8, 52, 23, 560811), timezone='UTC')
d = d.shift("Asia/Shanghai")
print(d)
d2 = d + datetime.timedelta(hours=2)
print(d2)
d3 = d - datetime.timedelta(hours=3)
print(d3)
# Delorean(datetime=datetime.datetime(2018, 5, 10, 16, 52, 23, 560811), timezone='Asia/Shanghai')
# Delorean(datetime=datetime.datetime(2018, 5, 10, 18, 52, 23, 560811), timezone='Asia/Shanghai')
# Delorean(datetime=datetime.datetime(2018, 5, 10, 13, 52, 23, 560811), timezone='Asia/Shanghai')

3. Delorean 高级使用

通常情况下我们不关心有多少微妙或者多少秒,因此Delorean提供了非常方便的过滤方式:

from delorean import Delorean

d = Delorean()
print(d)
# Delorean(datetime=datetime.datetime(2019, 3, 14, 4, 0, 50, 597357), timezone='UTC')
d.truncate('second')
# Delorean(datetime=datetime.datetime(2019, 3, 14, 4, 0, 50), timezone='UTC')
d.truncate('hour')
# Delorean(datetime=datetime.datetime(2019, 3, 14, 4, 0), timezone='UTC')
d.truncate('month')
# Delorean(datetime=datetime.datetime(2019, 3, 1, 0, 0), timezone='UTC')
d.truncate('year')
# Delorean(datetime=datetime.datetime(2019, 1, 1, 0, 0), timezone='UTC')

另外,datetime格式的字符串处理的时候转换需要标明各种各样的格式,在Delorean你直接parse就可以了:

from delorean import parse
parse("2011/01/01 00:00:00 -0700")
# Delorean(datetime=datetime.datetime(2011, 1, 1, 0, 0), timezone=pytz.FixedOffset(-420))
parse("2018-05-06")
# Delorean(datetime=datetime.datetime(2018, 6, 5, 0, 0), timezone='UTC')

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

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

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

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

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

这个神奇的工具,能自动将.py转换为.exe

Auto-py-to-exe 能够基于简单的GUI图形界面和Python中的 PyInstaller,将.py转换为.exe,非常容易使用,适合那些需要在windows上直接执行py文件但又没有Python运行环境的情景。

1. 安装和使用

通过 PyPI 安装

你可以使用PyPI安装此项目:

pip install auto-py-to-exe

然后运行它,在终端中执行以下命令:

auto-py-to-exe

通过 GitHub 安装

git clone https://github.com/brentvollebregt/auto-py-to-exe.git
cd auto-py-to-exe
python setup.py install

然后运行它,在终端中执行以下命令:

auto-py-to-exe

在本地通过 Github 运行(无需安装)

你可以通过以下步骤在本地运行此项目:

1. 克隆/下载 https://github.com/brentvollebregt/auto-py-to-exe

2. 打开 cmd 或终端并 cd 到该项目

3. 执行以下命令

python -m pip install -r requirements.txt

现在运行应用程序,执行:

python -m auto_py_to_exe

将在应用程序模式下打开一个Chrome窗口,并在其中运行本项目。

2. 使用本程序

1.选择您的脚本文件的位置(粘贴或使用文件浏览器),文件存在时轮廓将变为蓝色:

2. 选择其他选项并添加图标或附加文件之类的内容

3. 点击底部的蓝色大按钮进行转换

完成后当前终端所处目录的 output 文件夹中找到转换后的文件:

非常简单,大家有需要可以试试看。

参数使用

如果你不想使用可视化的GUI,也可以通过参数创建:

auto-py-to-exe [-nc] [-c [CONFIG]] [-o [PATH]] [filename]
参数类型描述
filenamepositional在用户界面中预先填写“脚本位置”字段。
-nc, –no-chromeoptional使用默认浏览器打开用户界面。 不会尝试寻找Chrome。
-nu, –no-uioptional不要试图在浏览器中打开界面。
-c [CONFIG], –config [CONFIG]optional提供配置文件(json)以预填充UI。 这些可以在设置选项卡中生成。
-o [PATH], –output-dir [PATH]optional设置默认输出目录。

当然,我建议还是使用GUI的方式,用起来比命令行的形式方便许多。不过你如果需要批量创建exe,那么确实参数形式更适合你。

导出导入配置

“设置”里有“配置导入和导出”部分,它可以将配置作为JSON字符串导出到剪贴板或文件,从而导出UI的当前状态。然后可以使用该JSON再次将配置导入到UI中,以重新填充所有字段。

3. 使用上出现问题

1.输出可执行文件很大

有时 pyinstaller 会自动添加它在你的环境中看到的包,即使你没有在被打包的项目中使用它们。这可能导致输出可执行文件的大小为数十到数百兆字节。

为了解决这个问题,最简单的方法是:

  1. 创建一个新的/干净的虚拟环境
  2. 将 auto-py-to-exe 安装到其中
  3. 为你的项目安装所需的模块
  4. 在这个虚拟环境中使用 auto-py-to-exe 来打包你的脚本

这样做意味着 pyinstaller 看不到你不需要捆绑的软件包,文件会被尽可能减小。

2.命令“python setup.py egg_info”失败,错误代码为 1

安装最新版 setuptools:

pip install --upgrade setuptools.

3.PermissionError: [Errno 13] 权限被拒绝: …

发生这种情况是因为你试图修改无权访问的目录中的文件。解决此问题的一种方法是通过以管理员身份打开 cmd 来运行具有管理员权限的脚本,然后 cd 到你希望输出的脚本的所在目录运行 auto-py-to-exe

更多的问题,可以在这篇文章中尝试查找解决方案:https://nitratine.net/blog/post/issues-when-using-auto-py-to-exe/

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

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

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

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

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

大型Python项目依赖树很烦?教你一招一键理清

你可能时常会遇到由于包的版本不匹配导致代码报错的问题,由于 pip freeze 将所有依赖项显示为二维列表,这时候如果想找到这个错误版本的包是比较麻烦的事情。这时候,有个工具你必须得知道,它就是 pipdeptree.

pipdeptree 是一个命令行实用程序,它能用于以依赖关系树可视化的形式显示已安装的python包。

它适用于全局安装在计算机上的各个模块软件包,也适用于Virtualenv等虚拟环境中的软件包。

1.安装

你只需要在你的虚拟环境中输入以下命令就能安装pipdeptree:

pip install pipdeptree

已通过测试的Python版本:2.7,3.5,3.6,3.7,3.8,3.9 以及 pypy2 和 pypy3.

2.用法和示例

pip freeze 和 pipdeptree 最大的区别如下:

# pip freeze 的显示
$ pip freeze
Flask==0.10.1
itsdangerous==0.24
Jinja2==2.11.2
-e git+git@github.com:naiquevin/lookupy.git@cdbe30c160e1c29802df75e145ea4ad903c05386#egg=Lookupy
MarkupSafe==0.22
pipdeptree @ file:///private/tmp/pipdeptree-2.0.0b1-py3-none-any.whl
Werkzeug==0.11.2

可见,pip freeze 最多只能显示一个依赖的列表,而在 pipdeptree ,每个模块的依赖关系能够非常直观地展示出来:

$ pipdeptree
Warning!!! Possibly conflicting dependencies found:
* Jinja2==2.11.2
 - MarkupSafe [required: >=0.23, installed: 0.22]
------------------------------------------------------------------------
Flask==0.10.1
  - itsdangerous [required: >=0.21, installed: 0.24]
  - Jinja2 [required: >=2.4, installed: 2.11.2]
    - MarkupSafe [required: >=0.23, installed: 0.22]
  - Werkzeug [required: >=0.7, installed: 0.11.2]
Lookupy==0.1
pipdeptree==2.0.0b1
  - pip [required: >=6.0.0, installed: 20.1.1]
setuptools==47.1.1
wheel==0.34.2

请注意这个 Warning,提示了你哪些模块会造成其依赖的模块版本发生冲突,这是非常有用的提示,很多时候问题就出现在这里。

不仅如此,如果存在循环性依赖,比如:

CircularDependencyA => CircularDependencyB => CircularDependencyA

它会进行如下提示:

$ pipdeptree --exclude pip,pipdeptree,setuptools,wheel
Warning!!! Cyclic dependencies found:
- CircularDependencyA => CircularDependencyB => CircularDependencyA
- CircularDependencyB => CircularDependencyA => CircularDependencyB
------------------------------------------------------------------------
wsgiref==0.1.2
argparse==1.2.1

如果你想生成 requirements.txt,可以这么做:

$ pipdeptree -f | tee locked-requirements.txt
Flask==0.10.1
  itsdangerous==0.24
  Jinja2==2.11.2
    MarkupSafe==0.23
  Werkzeug==0.11.2
gnureadline==8.0.0
-e git+git@github.com:naiquevin/lookupy.git@cdbe30c160e1c29802df75e145ea4ad903c05386#egg=Lookupy
pipdeptree @ file:///private/tmp/pipdeptree-2.0.0b1-py3-none-any.whl
  pip==20.1.1
setuptools==47.1.1
wheel==0.34.2

在确认没有冲突的依赖项后,甚至可以将其“锁定”,其中所有包都将固定到其当前安装的版本:

$ pipdeptree -f | sed 's/ //g' | sort -u > locked-requirements.txt

3. 可视化依赖树

为了能够可视化展示依赖树,我们需要安装GraphViz,我们需要安装GraphViz,安装GraphViz​的教程可见这篇文章:Python 一键转化代码为流程图。​安装完成后输入以下命令:

pipdeptree --graph-output png > dependencies.png

# pipdeptree --graph-output dot > dependencies.dot
# pipdeptree --graph-output pdf > dependencies.pdf
# pipdeptree --graph-output svg > dependencies.svg

支持四种格式的输出,这里png的输出效果如下:

效果还是非常不错的,大家如果有需要清理依赖的大型项目,可以用 pipdeptree 试一下。

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

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

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

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

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

超级方便的轻量级Python流水线工具,拥有漂亮的可视化界面!

Mara-pipelines 是一个轻量级的数据转换框架,具有透明和低复杂性的特点。其他特点如下:

  • 基于非常简单的Python代码就能完成流水线开发。
  • 使用 PostgreSQL 作为数据处理引擎。
  • 有Web界面可视化分析流水线执行过程。
  • 基于 Python 的 multiprocessing 单机流水线执行。不需要分布式任务队列。轻松调试和输出日志。
  • 基于成本的优先队列:首先运行具有较高成本(基于记录的运行时间)的节点。

此外,在Mara-pipelines的Web界面中,你不仅可以查看和管理流水线及其任务节点,你还可以直接触发这些流水线和节点,非常好用:

1.安装

由于使用了大量的依赖,Mara-pipelines 并不适用于Windows,如果你需要在Windows上使用Mara-pipelines,请使用docker或者windows下的linux子系统

使用pipe安装Mara-pipelines:

pip install mara-pipelines

或者:

pip install git+https://github.com/mara/mara-pipelines.git

2.使用示例

这是一个基础的流水线演示,由三个相互依赖的节点组成,包括 任务1(ping_localhost), 子流水线(sub_pipeline), 任务2(sleep):

# 注意,这个示例中使用了部分国外的网站,如果无法访问,请变更为国内网站。
from mara_pipelines.commands.bash import RunBash
from mara_pipelines.pipelines import Pipeline, Task
from mara_pipelines.ui.cli import run_pipeline, run_interactively

pipeline = Pipeline(
    id='demo',
    description='A small pipeline that demonstrates the interplay between pipelines, tasks and commands')

pipeline.add(Task(id='ping_localhost', description='Pings localhost',
                  commands=[RunBash('ping -c 3 localhost')]))

sub_pipeline = Pipeline(id='sub_pipeline', description='Pings a number of hosts')

for host in ['google', 'amazon', 'facebook']:
    sub_pipeline.add(Task(id=f'ping_{host}', description=f'Pings {host}',
                          commands=[RunBash(f'ping -c 3 {host}.com')]))

sub_pipeline.add_dependency('ping_amazon', 'ping_facebook')
sub_pipeline.add(Task(id='ping_foo', description='Pings foo',
                      commands=[RunBash('ping foo')]), ['ping_amazon'])

pipeline.add(sub_pipeline, ['ping_localhost'])

pipeline.add(Task(id='sleep', description='Sleeps for 2 seconds',
                  commands=[RunBash('sleep 2')]), ['sub_pipeline'])

可以看到,Task包含了多个commands,这些commands会用于真正地执行动作。而 pipeline.add 的参数中,第一个参数是其节点,第二个参数是此节点的上游。如:

pipeline.add(sub_pipeline, ['ping_localhost'])

则表明必须执行完 ping_localhost 才会执行 sub_pipeline.

为了运行这个流水线,需要配置一个 PostgreSQL 数据库来存储运行时信息、运行输出和增量处理状态:

import mara_db.auto_migration
import mara_db.config
import mara_db.dbs

mara_db.config.databases \
    = lambda: {'mara': mara_db.dbs.PostgreSQLDB(host='localhost', user='root', database='example_etl_mara')}

mara_db.auto_migration.auto_discover_models_and_migrate()

如果 PostgresSQL 正在运行并且账号密码正确,输出如下所示(创建了一个包含多个表的数据库):

Created database "postgresql+psycopg2://root@localhost/example_etl_mara"

CREATE TABLE data_integration_file_dependency (
    node_path TEXT[] NOT NULL, 
    dependency_type VARCHAR NOT NULL, 
    hash VARCHAR, 
    timestamp TIMESTAMP WITHOUT TIME ZONE, 
    PRIMARY KEY (node_path, dependency_type)
);

.. more tables

为了运行这个流水线,你需要:

from mara_pipelines.ui.cli import run_pipeline

run_pipeline(pipeline)

这将运行单个流水线节点及其 (sub_pipeline) 所依赖的所有节点:

run_pipeline(sub_pipeline, nodes=[sub_pipeline.nodes['ping_amazon']], with_upstreams=True)

3.Web 界面

我认为 mara-pipelines 最有用的是他们提供了基于Flask管控流水线的Web界面。

对于每条流水线,他们都有一个页面显示:

  • 所有子节点的图以及它们之间的依赖关系
  • 流水线的总体运行时间图表以及过去 30 天内最昂贵的节点(可配置)
  • 所有流水线节点及其平均运行时间和由此产生的排队优先级的表
  • 流水线最后一次运行的输出和时间线

对于每个任务,都有一个页面显示

  • 流水线中任务的上游和下游
  • 最近 30 天内任务的运行时间
  • 任务的所有命令
  • 任务最后运行的输出

此外,流水线和任务可以直接从网页端调用运行,这是非常棒的特点:

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

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

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

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

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

Vulture 一键找出项目中所有无效的Python代码

Vulture 可以在Python程序中查找未使用的代码。这对于清理和查找大型项目(代码库)中的错误非常有用。

不过由于Python的动态特性,像 Vulture 这样的静态代码分析器很可能会遗漏一些无效代码,此外,可能会将仅被隐式调用的代码标记为未使用。

尽管如此,Vulture对于提升代码质量来说可能是一个非常有用的工具。

1.功能

  • FAST:静态代码分析
  • 已测试
  • 与pyflies相辅相成,具有相同的输出语法
  • 可以按大小对未使用的类和函数进行排序 --sort-by-size
  • 支持Python>=3.6

2.准备

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

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

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

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

pip install vulture

3.用法

你可以直接使用命令行工具运行 vulture:

vulture myscript.py  # 或者
python3 -m vulture myscript.py  # 或者
vulture myscript.py mypackage/  # 或者
vulture myscript.py --min-confidence 100  # 只报告100%可能的无效代码

如果 vulture 没有被加进环境变量(如Windows系统下不会自动加到环境变量中),建议使用 python -m 的方式调用 vulture。

可见,命令的参数可以是 Python 文件或目录。对于每个目录,Vulture 会分析所有包含的 *.py文件。

Vulture 为每个无效代码块分配一个置信度值。100% 的置信度值意味着百分百的无效代码。

找到并删除无效代码后,再次运行 Vulture,因为它可能会发现更多的无效代码。

下面举个例子,参考下述代码:

import os

class Greeter:
    def greet(self):
        print("Hi")

def hello_world():
    message = "Hello, world!"
    greeter = Greeter()
    greet_func = getattr(greeter, "greet")
    greet_func()

if __name__ == "__main__":
    hello_world()

调用vulture:

vulture dead_code.py
# 或者
python -m vulture dead_code.py

输出效果如下:

dead_code.py:1: unused import 'os' (90% confidence)
dead_code.py:4: unused function 'greet' (60% confidence)
dead_code.py:8: unused variable 'message' (60% confidence)

Vulture 正确地将“os”和“message”报告为未使用,但未能检测到实际使用了“greet”。处理此类误报的推荐方法是创建一个白名单 Python 文件。见下面第四点。

4.处理误报

当 Vulture 错误地将代码块报告为未使用时,有多种选择来抑制误报。如果修复误报也可以使其他用户受益,请提交问题报告。

白名单

推荐的选项是将报告为”未使用的”已使用代码添加到 Python 模块,并将其添加到扫描路径列表中。要自动获取这样的白名单,请传递 --make-whitelist 给 Vulture:

vulture mydir --make-whitelist > whitelist.py
vulture mydir whitelist.py

请注意,生成的 whitelist.py 文件将包含有效的 Python 语法,但为了让 Python 能够运行它,通常需要进行一些修改。

忽略文件

如果要忽略整个文件或目录,请使用--exclude 参数(例如,--exclude *settings.py,docs/)。

Flake8 noqa 注释

为了与flake8兼容,Vulture 支持F401 和 F841错误代码以忽略未使用的导入 ( # noqa: F401) 和未使用的局部变量 ( # noqa: F841)。但是,我们建议使用白名单而不是noqa注释,因为noqa注释会给代码增加视觉干扰并使其更难阅读。

忽略名称

你还可以使用 --ignore-names foo*,ba[rz] 让 Vulture 忽略所有以 foo 开头的及 barbaz 的名称。此外,该 --ignore-decorators 选项可用于忽略用给定装饰器装饰的函数。这在 Flask 项目中很有帮助,您可以在其中使用装饰器 --ignore-decorators "@app.route" 忽略所有 @app.route 函数。

我们建议使用白名单代替 --ignore-names 或 --ignore-decorators ,因为白名单在传递给 Vulture 时会自动检查语法正确性。

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

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

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

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

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

Addict 写起来令人极其舒适的字典模块

Addit 是一个Python模块,除了提供标准的字典语法外,Addit生成的字典的值既可以使用属性来获取,也可以使用属性进行设置。

这意味着你不用再写这样的字典了:

 

body = {
    'query': {
        'filtered': {
            'query': {
                'match': {'description': 'addictive'}
            },
            'filter': {
                'term': {'created_by': 'Mats'}
            }
        }
    }
}

相反,你只需编写以下三行就能完成目的:

body = Dict()
body.query.filtered.query.match.description = 'addictive'
body.query.filtered.filter.term.created_by = 'Mats'

1.安装

你可以通过安装pip

pip install addict

或通过conda

conda install addict -c conda-forge

Addit 在Python2.7+和Python3上都可以运行。

2.用法

Addict 继承自dict,但在访问和设置其值方面更加灵活。使用字典现在是一种乐趣!

设置嵌套词典的项是极其舒服的:

>>> from addict import Dict
>>> mapping = Dict()
>>> mapping.a.b.c.d.e = 2
>>> mapping
{'a': {'b': {'c': {'d': {'e': 2}}}}}

如果Dict是用任何可迭代值实例化的,它将遍历并克隆这些值,然后写入到对应的属性及值中,比如:

>>> mapping = {'a': [{'b': 3}, {'b': 3}]}
>>> dictionary = Dict(mapping)
>>> dictionary.a[0].b
3

mapping['a']不再与dictionary['a']相同。

>>> mapping['a'] is dictionary['a']
False

当然,此特点仅限于构造函数,而不是在使用属性或设置值时:

>>> a = Dict()
>>> b = [1, 2, 3]
>>> a.b = b
>>> a.b is b
True

3.要牢记的事情

记住,int不是有效的属性名,因此必须使用 get/setitem 语法 设置/获取 非字符串的dict键:

>>> addicted = Dict()
>>> addicted.a.b.c.d.e = 2
>>> addicted[2] = [1, 2, 3]
{2: [1, 2, 3], 'a': {'b': {'c': {'d': {'e': 2}}}}}

不过,你可以随意混合使用这两种语法:

>>> addicted.a.b['c'].d.e
2

4.属性,如键、item等

Addit 不会让你覆盖dict的属性,因此以下操作将不起作用

>>> mapping = Dict()
>>> mapping.keys = 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "addict/addict.py", line 53, in __setattr__
raise AttributeError("'Dict' object attribute '%s' is read-only" % name)
AttributeError: 'Dict' object attribute 'keys' is read-only

不过,使用下面这种方式就可以:

>>> a = Dict()
>>> a['keys'] = 2
>>> a
{'keys': 2}
>>> a['keys']
2

5.默认值

对于不在字典中的键,Addit的行为如defaultdict(Dict),因此丢失的键返回一个空的Dict而不是抛出KeyError如果此行为不是所需的,则可以使用以下方式恢复抛出KeyError:

>>> class DictNoDefault(Dict):
>>> def __missing__(self, key):
>>> raise KeyError(key)

但请注意,这样会失去速记赋值功能(addicted.a.b.c.d.e = 2)

6.转化为普通字典

如果你觉得将 Addict 传递到其他函数或模块并不安全,请使用to_dict()方法,它返回会把 Addict 转化为普通字典。

>>> regular_dict = my_addict.to_dict()
>>> regular_dict.a = 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'a'

当您希望在几行代码中创建嵌套的字典,然后将其发送到不同的函数或模块时,这非常适合:

body = Dict()
body.query.filtered.query.match.description = 'addictive'
body.query.filtered.filter.term.created_by = 'Mats'
third_party_module.search(query=body.to_dict())

7.计数

Dict轻松访问和修改深度嵌套属性的能力使其成为计数的理想选择。使用Addict,你还可以容易允许按多个级别计数,内部使用的原理是collections.Counter

比如以下数据:

data = [
    {'born': 1980, 'gender': 'M', 'eyes': 'green'},
    {'born': 1980, 'gender': 'F', 'eyes': 'green'},
    {'born': 1980, 'gender': 'M', 'eyes': 'blue'},
    {'born': 1980, 'gender': 'M', 'eyes': 'green'},
    {'born': 1980, 'gender': 'M', 'eyes': 'green'},
    {'born': 1980, 'gender': 'F', 'eyes': 'blue'},
    {'born': 1981, 'gender': 'M', 'eyes': 'blue'},
    {'born': 1981, 'gender': 'F', 'eyes': 'green'},
    {'born': 1981, 'gender': 'M', 'eyes': 'blue'},
    {'born': 1981, 'gender': 'F', 'eyes': 'blue'},
    {'born': 1981, 'gender': 'M', 'eyes': 'green'},
    {'born': 1981, 'gender': 'F', 'eyes': 'blue'}
]

如果你想计算有多少人出生在born性别的gender使用eyes眼睛,你可以很容易地计算出这些信息:

counter = Dict()

for row in data:
born = row['born']
gender = row['gender']
eyes = row['eyes']
counter
[born][gender][eyes] += 1 print(counter)

{1980: {'M': {'blue': 1, 'green': 3}, 'F': {'blue': 1, 'green': 1}}, 1981: {'M': {'blue': 2, 'green': 1}, 'F': {'blue': 2, 'green': 1}}}

8.更新

普通字典的更新方式如下:

>>> d = {'a': {'b': 3}}
>>> d.update({'a': {'c': 4}})
>>> print(d)
{'a': {'c': 4}}

addict的更新方式如下,它会递归并实际更新嵌套的字典:

>>> D = Dict({'a': {'b': 3}})
>>> D.update({'a': {'c': 4}})
>>> print(D)
{'a': {'b': 3, 'c': 4}}

9.为什么需要addict

这个模块完全是从用Python创建Elasticsearch查询的繁琐过程中发展而来的。每当你发现自己在写了很复杂的字典逻辑时,只要记住你没有必要这样做,使用 Addict 就行。

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

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

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

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

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

Tqsdk-python-天勤量化开发包,期货量化,实时行情/历史数据/实盘交易

TqSdk天勤量化交易策略程序开发包

TqSdk是一个由信易科技发起并贡献主要代码的开源Python库.依托快期多年积累成熟的交易及行情服务器体系,TqSdk支持用户使用极少的代码量构建各种类型的量化交易策略程序,并提供包含期货、期权、股票的历史数据-实时数据-开发调试-策略回测-模拟交易-实盘交易-运行监控-风险管理全套解决方案

from tqsdk import TqApi, TqAuth, TqAccount, TargetPosTask

api = TqApi(TqAccount("H海通期货", "4003242", "123456"), auth=TqAuth("信易账户", "账户密码"))      # 创建 TqApi 实例, 指定交易账户
q_1910 = api.get_quote("SHFE.rb1910")                         # 订阅近月合约行情
t_1910 = TargetPosTask(api, "SHFE.rb1910")                    # 创建近月合约调仓工具
q_2001 = api.get_quote("SHFE.rb2001")                         # 订阅远月合约行情
t_2001 = TargetPosTask(api, "SHFE.rb2001")                    # 创建远月合约调仓工具

while True:
  api.wait_update()                                           # 等待数据更新
  spread = q_1910["last_price"] - q_2001["last_price"]        # 计算近月合约-远月合约价差
  print("当前价差:", spread)
  if spread > 250:
    print("价差过高: 空近月,多远月")                            
    t_1910.set_target_volume(-1)                              # 要求把1910合约调整为空头1手
    t_2001.set_target_volume(1)                               # 要求把2001合约调整为多头1手
  elif spread < 200:
    print("价差回复: 清空持仓")                               # 要求把 1910 和 2001合约都调整为不持仓
    t_1910.set_target_volume(0)
    t_2001.set_target_volume(0)

要快速了解如何使用TqSdk,可以访问我们的十分钟快速入门指南

架构

功能

TqSdk提供的功能可以支持从简单到复杂的各类策略程序

  • 公司级数据运维,提供当前所有可交易合约从上市开始的全部Tick数据和K线数据
  • 支持市场上90%的期货公司实盘交易
  • 支持模拟交易
  • 支持Tick级和K线级回测,支持复杂策略回测
  • 提供近百个技术指标函数及源码
  • 用户无须建立和维护数据库,行情和交易数据全在内存数据库,无访问延迟
  • 优化支持熊猫麻木的
  • 无强制框架结构,支持任意复杂度的策略,在一个交易策略程序中使用多个品种的K线/实时行情并交易多个品种
  • 配合开发者支持工具,能够进行交易信号打点,支持自定义指标画图

安装

TqSdk仅支持Python3.6及更高版本。要安装TqSdk,可使用PIP:

$ pip install tqsdk

文档

在线阅读HTML版本文档:https://doc.shinnytech.com/tqsdk/latest

在线问答社区:https://www.shinnytech.com/qa

知乎账户[天勤量化]:https://www.zhihu.com/org/tian-qin-liang-hua/activities

用户交流QQ群:619870862(目前只允许给我们点过STAR的同学加入,加群时请提供GitHub用户名)

GUI

TqSdk本身自带的WEB_GUI功能,简单一行参数即可支持调用图形化界面,详情参考web_gui

关于我们

信易科技是专业的期货软件供应商和交易所授权行情服务商.旗下的快期系列产品已为市场服务超过10年。TqSdk是公司开源计划的一部分