中企动力 > 头条 > python3中的

网站性能检测评分

注:本网站页面html检测工具扫描网站中存在的基本问题,仅供参考。

python3中的

机器学习如何从Python 2迁移到Python 3 公司视频课程

img

Gordon

关注

出品 | FlyAI

编译 | 林椿眄

编辑 | Donna

Python 已经成为机器学习及其他科学领域中的主流语言。它不但与多种深度学习框架兼容,而且还包含优秀的工具包和依赖库,方便我们对数据进行预处理和可视化操作。

据最新消息,到2019 年底,Numpy 等很多科学计算工具包都将停止支持Python 2版本,而 2018 年后 Numpy 的所有新功能版本也都将只支持 Python 3。

为了使初学者能够轻松地从 Python 2 向 Python 3 实现迁移,我收集了一些 Python 3 的功能,希望对大家有所帮助。

使用 pathlib 模块来更好地处理路径

pathlib 是 Python 3默认的用于处理数据路径的模块,它能够帮助我们避免使用大量的 os.path.joins语句:

from pathlib import Path dataset = 'wiki_images'datasets_root = Path('/path/to/datasets/') train_path = datasets_root / dataset / 'train'test_path = datasets_root / dataset / 'test'for image_path in train_path.iterdir(): with image_path.open() as f: # note, open is a method of Path object # do something with an image

在Python2中,我们需要通过级联字符串的形成来实现路径的拼接。而现在有了pathlib模块后,数据路径处理将变得更加安全、准确,可读性更强。

此外,pathlib.Path含有大量的方法,这样Python的初学者将不再需要搜索每个方法:

p.exists() p.is_dir() p.parts() p.with_name('sibling.png') # only change the name, but keep the folderp.with_suffix('.jpg') # only change the extension, but keep the folder and the namep.chmod(mode)p.rmdir()

使用pathlib还将大大节约你的时间。更多功能请查看:

官方文档 - https://docs.python.org/3/library/pathlib.html参考信息 - https://pymotw/3/pathlib/

类型提示(Type hinting)成为Python3中的新成员

下面是在编译器PyCharm 中,类型提示功能的一个示例:

Python 不只是一门脚本的语言,如今的数据流程还包括大量的逻辑步骤,每一步都包括不同的框架(有时也包括不同的逻辑)。

Python3中引入了类型提示工具包来处理复杂的大型项目,使机器可以更好地对代码进行验证。而在这之前,不同的模块需要使用自定义的方式,对文档中的字符串指定类型 (注意:PyCharm可以将旧的文档字符串转换成新的类型提示)。

下面是一个简单的代码示例,利用类型提示功能来处理不同类型的数据:

def repeat_each_entry(data): """ Each entry in the data is doubled """ index = numpy.repeat(numpy.arange(len(data)), 2) return data[index]

上述代码对多维的 numpy.array、astropy.Table 和 astropy.Column、bcolz、cupy、mxnet.ndarray 等操作同样适用。

这段代码还可用于 pandas.Series 操作,但是这种形式是错误的:

repeat_each_entry(pandas.Series(data=[0, 1, 2], index=[3, 4, 5])) # returns Series with Nones inside

这仅仅是一段两行的代码。所以,复杂系统的行为是非常难预测的,有时一个函数就可能导致整个系统的错误。因此,明确地了解哪些类型方法,并在这些类型方法未得到相应参数的时候发出错误提示,这对于大型系统的运作是很有帮助的。

def repeat_each_entry(data: Union[numpy.ndarray, bcolz.carray]):

如果你有一个很棒的代码库,诸如 MyPy这样的类型提示工具将可能成为一个大型项目的集成流程中的一部分。不幸的是,类型提示功能还没办法强大到为 ndarrays/tensors 这种细粒度类型发出提示。或许,不久的将来我们就可以拥有这样全面的的类型提示工具,这将成为数据科学领域需要的强大功能。

从类型提示(运行前)到类型检查(运行时)

默认情况下,函数的注释对于代码的运行是没有影响的,它只是帮你指出每段代码所要做的工作。

在代码运行阶段,很多时候类型提示工具是不起作用的。这种情况你可以使用 enforce 等工具,强制性对代码进行类型检查,同时也可以帮助你调试代码。

@enforce.runtime_validationdef foo(text: str) -> None: print(text) foo('Hi') # okfoo(5) # fails@enforce.runtime_validationdef any2(x: List[bool]) -> bool: return any(x)any ([False, False, True, False]) # Trueany2([False, False, True, False]) # Trueany (['False']) # Trueany2(['False']) # failsany ([False, None, "", 0]) # Falseany2([False, None, "", 0]) # fails

函数注释的其他用途

正如上面我们提到的,函数的注释部分不仅不会影响代码的执行,还会提供可以随时使用的一些元信息(meta-information)。

例如,计量单位是科学界的一个普遍难题,Python3中的astropy包提供了一个简单的装饰器(Decorator)来控制输入的计量单位,并将输出转换成相应的单位。

# Python 3from astropy import units as u@u.quantity_input()def frequency(speed: u.meter / u.s, wavelength: u.m) -> u.terahertz: return speed / wavelength frequency(speed=300_000 * u.km / u.s, wavelength=555 * u.nm)# output: 540.5405405405404 THz, frequency of green visible light

如果你需要用Python处理表格类型的科学数据,你可以尝试astropy包,体验一下计量单位随意转换的方便性。你还可以针对某个应用专门定义一个装饰器,用同样的方式来控制或转换输入和输出的计量单位。

通过 @ 实现矩阵乘法

下面,我们实现一个最简单的机器学习模型,即带 L2 正则化的线性回归 (如岭回归模型),来对比 Python2 和 Python3 之间的差别:

# l2-regularized linear regression: || AX - b ||^2 + alpha * ||x||^2 -> min# Python 2X = np.linalg.inv(np.dot(A.T, A) + alpha * np.eye(A.shape[1])).dot(A.T.dot(b))# Python 3X = np.linalg.inv(A.T @ A + alpha * np.eye(A.shape[1])) @ (A.T @ b

在 Python3 中,以@作为矩阵乘法符号使得代码整体的可读性更强,且更容易在不同的深度学习框架间进行转译:因为一些代码如 X @ W + b[None, :]在 numpy、cupy、pytorch 和 tensorflow 等不同库中都表示单层感知机。

使用 ** 作为通配符

Python2 中使用递归文件夹的通配符并不是很方便,因此可以通过定制的 glob2 模块来解决这个问题。递归 flag 在 Python 3.6 中得到了支持。

import glob# Python 2found_images = \ glob.glob('/path*.jpg') \ + glob.glob('/path*.jpg') \ + glob.glob('/path***.jpg') # Python 3found_images = glob.glob('/path*.jpg', recursive=True)

Python3 中更好的选择是使用 pathlib:(缺少个import)

# Python 3found_images = pathlib.Path('/path/').glob('**/*.jpg')

Python3中的print函数

诚然,print 在 Python3 中是一个函数,使用 print 需要加上圆括弧(),虽然这是个麻烦的操作,但它还是具有一些优点:

使用文件描述符的简单句法:

print >>sys.stderr, "critical error" # Python 2print("critical error", file=sys.stderr) # Python 3

在不使用str.join情况下能够输出 tab-aligned 表格:

# Python 3print(*array, sep='\t')print(batch, epoch, loss, accuracy, time, sep='\t')

修改与重新定义 print 函数的输出:

# Python 3_print = print # store the original print functiondef print(*args, **kargs): pass # do something useful, e.g. store output to some file

在 Jupyter notebook 中,这种形式能够记录每一个独立的文档输出,并在出现错误的时候追踪到报错的文档。这能方便我们快速定位并解决错误信息。因此我们可以重写 print 函数。

在下面的代码中,我们可以使用上下文管理器来重写 print 函数的行为:

@contextlib.contextmanagerdef replace_print(): import builtins _print = print # saving old print function # or use some other function here builtins.print = lambda *args, **kwargs: _print('new printing', *args, **kwargs) yield builtins.print = _printwith replace_print():

但是,重写print函数的行为,我们并不推荐,因为它会引起系统的不稳定。

print函数可以结合列表生成器或其它语言结构一起使用。

# Python 3result = process(x) if is_valid(x) else print('invalid item: ', x)

f-strings 可作为简单和可靠的格式化

默认的格式化系统提供了一些灵活性操作。但在数据实验中这些操作不仅不是必须的,还会导致代码的修改变得冗长和琐碎。

而数据科学通常需要以固定的格式,迭代地打印出一些日志信息,所使用的代码如下:

# Python 2print('{batch:3} {epoch:3} / {total_epochs:3} accuracy: {acc_mean:0.4f}±{acc_std:0.4f} time: {avg_time:3.2f}'.format( batch=batch, epoch=epoch, total_epochs=total_epochs, acc_mean=numpy.mean(accuracies), acc_std=numpy.std(accuracies), avg_time=time / len(data_batch) ))# Python 2 (too error-prone during fast modifications, please avoid):print('{:3} {:3} / {:3} accuracy: {:0.4f}±{:0.4f} time: {:3.2f}'.format( batch, epoch, total_epochs, numpy.mean(accuracies), numpy.std(accuracies), time / len(data_batch) ))

样本输出为:

120 12 / 300 accuracy: 0.8180±0.4649 time: 56.60

Python 3.6 中引入了格式化字符串 (f-strings):

f# Python 3.6+print(f'{batch:3} {epoch:3} / {total_epochs:3} accuracy: {numpy.mean(accuracies):0.4f}±{numpy.std(accuracies):0.4f} time: {time / len(data_batch):3.2f}')

另外,这对于查询语句的书写也是非常方便的:

query = f"INSERT INTO STATION VALUES (13, '{city}', '{state}', {latitude}, {longitude})"

「true pision」和「integer pision」之间的明显区别

虽然说对于系统编程来说,Python3所提供的改进还远远不够,但这些便利对于数据科学来说已经足够。

data = pandas.read_csv('timing.csv') velocity = data['distance'] / data['time']

Python 2 中的结果依赖于『时间』和『距离』(例如,以米和秒为单位),关注其是否被保存为整数。

而在 Python 3 中,结果的表示都是精确的,因为除法运算得到的都是精确的浮点数。

另一个例子是整数除法,现在已经作为明确的运算:

n_gifts = money // gift_price # correct for int and float arguments

值得注意的是,整除运算可以应用到Python的内建类型和由numpy、pandas等数据包提供的自定义类型。

严格排序

下面是一个严格排序的例子:

# All these comparisons are illegal in Python 33 < '3'2 < None(3, 4) < (3, None)(4, 5) < [4, 5]# False in both Python 2 and Python 3(4, 5) == [4, 5]

严格排序的主要功能有:

防止不同类型实例之间的偶然性排序。

sorted([2, '1', 3]) # invalid for Python 3, in Python 2 returns [2, 3, '1']

在处理原始数据时帮助我们发现存在的问题。此外,严格排序对None值的合适性检查是(这对于两个版本的 Python 都适用):

if a is not None: passif a: # WRONG check for None pass

自然语言处理中的Unicode编码

下面来看一个自然语言处理任务:

s = '您好'print(len(s))print(s[:2])

比较两个版本Python的输出:

Python2: 6\n

Python3: 2\n 您好

再来看个例子:

x = u'со' x += 'co' # ok x += 'со' # fail

在这里,Python 2 会报错,而 Python 3 能够正常工作。因为我在字符串中使用了俄文字母,对于Python2 是无法识别或编码这样的字符。

Python 3 中的 strs 是 Unicode 字符串,这对非英语文本的自然语言处理任务来说将更加地方便。还有些其它有趣的应用,例如:

'a'< type < u'a' # Python 2: True'a' < u'a' # Python 2: False

from collections import Counter Counter('Mbelstück')

Python 2: Counter({'\xc3': 2, 'b': 1, 'e': 1, 'c': 1, 'k': 1, 'M': 1, 'l': 1, 's': 1, 't': 1, '\xb6': 1, '\xbc': 1})

Python 3: Counter({'M': 1, '': 1, 'b': 1, 'e': 1, 'l': 1, 's': 1, 't': 1, 'ü': 1, 'c': 1, 'k': 1})

对于这些,Python 2 也能正常地工作,但 Python 3 的支持更为友好。

保留词典和**kwargs 的顺序

CPython 3.6+ 的版本中字典的默认行为是一种类似 OrderedDict 的类,但最新的 Python3.7 版本,此类已经得到了全面的支持。这就要求在字典理解、json 序列化/反序列化等操作中保持字典原先的顺序。

下面来看个例子:

import json x = {str(i):i for i in range(5)} json.loads(json.dumps(x))# Python 2{u'1': 1, u'0': 0, u'3': 3, u'2': 2, u'4': 4}# Python 3{'0': 0, '1': 1, '2': 2, '3': 3, '4': 4}

这种保顺性同样适用于 Python3.6 版本中的 **kwargs:它们的顺序就像参数中显示的那样。当设计数据流程时,参数的顺序至关重要。

以前,我们必须以这样繁琐的方式来编写:

from torch import nn # Python 2 model = nn.Sequential(OrderedDict([ ('conv1', nn.Conv2d(1,20,5)), ('relu1', nn.ReLU()), ('conv2', nn.Conv2d(20,64,5)), ('relu2', nn.ReLU()) ])) # Python 3.6+, how it *can* be done, not supported right now in pytorch model = nn.Sequential( conv1=nn.Conv2d(1,20,5), relu1=nn.ReLU(), conv2=nn.Conv2d(20,64,5), relu2=nn.ReLU()) )

注意到了吗?名称的唯一性也会被自动检查。

迭代拆封

Python3 中引入迭代式拆封功能,下面来看一段代码:

# handy when amount of additional stored info may vary between experiments, but the same code can be used in all casesmodel_paramteres, optimizer_parameters, *other_params = load(checkpoint_name)# picking two last values from a sequence*prev, next_to_last, last = values_history# This also works with any iterables, so if you have a function that yields e.g. qualities,# below is a simple way to take only last two values from a list *prev, next_to_last, last = iter_train(args)

默认的 pickle 引擎为数组提供更好的压缩

Python3 中引入 pickle 引擎,为数组提供更好的压缩,节省参数空间:

# Python 2import cPickle as pickleimport numpyprint len(pickle.dumps(numpy.random.normal(size=[1000, 1000])))# result: 23691675# Python 3import pickleimport numpylen(pickle.dumps(numpy.random.normal(size=[1000, 1000])))# result: 8000162

这个小的改进节省了3倍的空间,而且运行阶段速度更快。实际上,如果不关心速度的话,类似的压缩性能也可以通过设置参数 protocol=2 来实现,但是用户经常会忽略这个选项或者...

伪随机整数生成在Python3中的实现,看完之后马上变成高手 营销视频课程

img

弗兰克

关注

人生苦短,我用Python,这句话让我对Python发生了兴趣,并开始学习它,希望一天可以熟练掌握它,然后可以充满诚意和期待对某些骨骼清奇少年说一句:人生苦短,快用Python。

但是我的学习之路比较坎坷,学习的时间就像今天要谈的主题一样是完全随机的:哪天学,学些什么,连续学习多长时间,这些都是老天才知道的,完全不像Python的随机数生成函数是Bulit-in。于是,至今仍是一名想用Python的门外汉,不过既然这学习的机会仍在随机发生着,那就当然不能放弃,毕业随机数总会有产生的那一天。

话不多说,进入正题。这里说的随机数生成是指随机生成一个整数,而不是其它的以数字组合、数字字母组合的序列或者字典等,这个是今天主题,不能跑偏。Python3 的随机数生成是通过其自带的random模块中的函数来实现的,而random模块的基石是 random()函数,这也是今天要介绍的第一个角色。

random.random()返回一个[0.0, 1.0)之间的随机浮点数,于是利用这个函数获取一个随机整数的方法便是:int(n*random.random()),例如a = int(456*random.random())

第二个要介绍的函数是random.randint(start, stop),start和stop 必须都是整数,返回一个整数N,N满足start=

第三个函数是random.randrange(n)和random.range(start,stop,step),前者返回一个整数N满足0=

第四个函数是random.choice(),它的工作原理和random.randrange是类似的,从一个非空序列list中返回一个随机选择值。例如d = random.choice(range(1,90)).

看到没,so easy,利用这几个函数就可以在随机生成整数的大道上肆意奔跑了,祝屏幕前的你,当然也包括我自己能够早日完成修炼,任性地对别人说,人生苦短,我用Python。

一个快速将python2代码批量转为python3代码的好方法 互联网视频课程

img

詹炳

关注

由于python存在python2和python3两个主要的版本方向,经常会有将python2的代码转到python3的环境下运行的需求。尤其是跑一些神经网络的代码时有很多是在python2的环境下写的。在python3下运行会遇见很多不兼容,最常见的就是python3中print函数必须加()而python2中不是。一个一个修改这种错误又非常麻烦。

此时一种方式是再安装一个python2,比如下载anaconda对应的python2的版本,管理相关的库,运行的时候指定python2运行。不过如果是运行依赖比较多的代码可能需要在python2的环境安装许多包。

这里介绍一个python3自带的脚本2to3.py,可以将python2的程序自动转为python3的形式,节省了很多修改细节的时间。这个脚本在Python安装目录下Toolsscripts文件夹下,如果是利用anaconda3安装的python3,就在anaconda3/Tools/scripts中,如下图:

这个文件实际是可以复制到电脑任何位置使用的,当然也可以就在这个位置利用cmd使用,里面的代码也很简单,只有几行:

使用方法也很简单,如果我需要转换某个python文件,比如E盘根目录下的test.py,只需要在命令行里输入

python 2to3.py -w E:/test.py

如果需要转换某个文件夹下的所有文件,例如E盘test文件夹下的所有文件,只需要在命令行里输入

python 2to3.py -w E:/test/

就是这么简单就可以完成python2代码像python3代码的变换,当然目前对于一些比较复杂的依赖这种方法还不能完全转换,还需要根据运行错误调整,不过已经可以节省很多的时间啦。

企业里Python2和3哪个用的多?为什么? 企业视频课程

img

白鲨

关注

python2和python3的差异

如果你是一个初学者,或许你曾经触摸过其他的编程言语,你可能不知道,在开端学习python的时分都会遇到一个比较让人很头疼的问题:版别问题!!是学习python2 仍是学习 python3 ?这是十分让人纠结的!

查找一下便会发现python3 和 python2 是不兼容的,并且差异比较大,究竟学习哪个版别呢?

所以先学 Python2 仍是 Python3 都不是问题,或许说都是问题。可是现在总算不必纠结这个问题了!哈哈,好开心

因为一个开发者已经发布了一个网站来倒计时Python 2.7的“退休”。

能够看出,Python 2.7有望在两年后退休。

开发商表明,因为官方的日期没有发布,估计Python 2.7会在2020年4月12日退休,这是时刻的时分,pycon将举办。

Python 2,感谢您多年的忠诚服务。

巨蟒3,现在你在舞台上。

Python 2.7是2 x系列的最终一个版别。它的继任者Python 3在2008年12月发布,但它与2。X系列不兼容。3的3的特征和语法被移植回2.6和2.7。2.7的支撑时刻至少为10年,并将在2020之前供给过错批改。

怎么转换为Python 3?

如果您的主代码仍然根据Python 2,这是完全能够了解的。最流行的包PyPI上现在能够运转在Python 2和Python 3,添加更多的日常。为了简化转换,官方搬迁指南供给了在Python 3中运转Python 2代码的主张。

所以我主张:

1. 如果是你在企业中,需求用到python而学习python的话,那就要看企业的使用python的版别进行学习;

2. 如果想要更多的老练解决方案,最少的bug,最安稳的使用那就用python2 ;

3. 如果你是在读大学的学生,那我主张你学习python3,比及结业的时分或许python已经成为了干流。

另外,选2仍是3一般都是编程小白才会考虑。考虑的起点是作为一个初学者,有时候在学习的过程中会出现一些问题或者会参考一些项目去学习,这个时候会想一下,2是干流或者是3。已然刚学何不找个干流的。其实不管是2仍是3,只需照这一个学,就可以了。中心的差异在学习的时候也能更好的去加深一些形象

机器学习如何从Python 2迁移到Python 3 推广视频课程

img

Tyler

关注

出品 | FlyAI

编译 | 林椿眄

编辑 | Donna

Python 已经成为机器学习及其他科学领域中的主流语言。它不但与多种深度学习框架兼容,而且还包含优秀的工具包和依赖库,方便我们对数据进行预处理和可视化操作。

据最新消息,到2019 年底,Numpy 等很多科学计算工具包都将停止支持Python 2版本,而 2018 年后 Numpy 的所有新功能版本也都将只支持 Python 3。

为了使初学者能够轻松地从 Python 2 向 Python 3 实现迁移,我收集了一些 Python 3 的功能,希望对大家有所帮助。

使用 pathlib 模块来更好地处理路径

pathlib 是 Python 3默认的用于处理数据路径的模块,它能够帮助我们避免使用大量的 os.path.joins语句:

from pathlib import Path dataset = 'wiki_images'datasets_root = Path('/path/to/datasets/') train_path = datasets_root / dataset / 'train'test_path = datasets_root / dataset / 'test'for image_path in train_path.iterdir(): with image_path.open() as f: # note, open is a method of Path object # do something with an image

在Python2中,我们需要通过级联字符串的形成来实现路径的拼接。而现在有了pathlib模块后,数据路径处理将变得更加安全、准确,可读性更强。

此外,pathlib.Path含有大量的方法,这样Python的初学者将不再需要搜索每个方法:

p.exists() p.is_dir() p.parts() p.with_name('sibling.png') # only change the name, but keep the folderp.with_suffix('.jpg') # only change the extension, but keep the folder and the namep.chmod(mode)p.rmdir()

使用pathlib还将大大节约你的时间。更多功能请查看:

官方文档 - https://docs.python.org/3/library/pathlib.html参考信息 - https://pymotw/3/pathlib/

类型提示(Type hinting)成为Python3中的新成员

下面是在编译器PyCharm 中,类型提示功能的一个示例:

Python 不只是一门脚本的语言,如今的数据流程还包括大量的逻辑步骤,每一步都包括不同的框架(有时也包括不同的逻辑)。

Python3中引入了类型提示工具包来处理复杂的大型项目,使机器可以更好地对代码进行验证。而在这之前,不同的模块需要使用自定义的方式,对文档中的字符串指定类型 (注意:PyCharm可以将旧的文档字符串转换成新的类型提示)。

下面是一个简单的代码示例,利用类型提示功能来处理不同类型的数据:

def repeat_each_entry(data): """ Each entry in the data is doubled """ index = numpy.repeat(numpy.arange(len(data)), 2) return data[index]

上述代码对多维的 numpy.array、astropy.Table 和 astropy.Column、bcolz、cupy、mxnet.ndarray 等操作同样适用。

这段代码还可用于 pandas.Series 操作,但是这种形式是错误的:

repeat_each_entry(pandas.Series(data=[0, 1, 2], index=[3, 4, 5])) # returns Series with Nones inside

这仅仅是一段两行的代码。所以,复杂系统的行为是非常难预测的,有时一个函数就可能导致整个系统的错误。因此,明确地了解哪些类型方法,并在这些类型方法未得到相应参数的时候发出错误提示,这对于大型系统的运作是很有帮助的。

def repeat_each_entry(data: Union[numpy.ndarray, bcolz.carray]):

如果你有一个很棒的代码库,诸如 MyPy这样的类型提示工具将可能成为一个大型项目的集成流程中的一部分。不幸的是,类型提示功能还没办法强大到为 ndarrays/tensors 这种细粒度类型发出提示。或许,不久的将来我们就可以拥有这样全面的的类型提示工具,这将成为数据科学领域需要的强大功能。

从类型提示(运行前)到类型检查(运行时)

默认情况下,函数的注释对于代码的运行是没有影响的,它只是帮你指出每段代码所要做的工作。

在代码运行阶段,很多时候类型提示工具是不起作用的。这种情况你可以使用 enforce 等工具,强制性对代码进行类型检查,同时也可以帮助你调试代码。

@enforce.runtime_validationdef foo(text: str) -> None: print(text) foo('Hi') # okfoo(5) # fails@enforce.runtime_validationdef any2(x: List[bool]) -> bool: return any(x)any ([False, False, True, False]) # Trueany2([False, False, True, False]) # Trueany (['False']) # Trueany2(['False']) # failsany ([False, None, "", 0]) # Falseany2([False, None, "", 0]) # fails

函数注释的其他用途

正如上面我们提到的,函数的注释部分不仅不会影响代码的执行,还会提供可以随时使用的一些元信息(meta-information)。

例如,计量单位是科学界的一个普遍难题,Python3中的astropy包提供了一个简单的装饰器(Decorator)来控制输入的计量单位,并将输出转换成相应的单位。

# Python 3from astropy import units as u@u.quantity_input()def frequency(speed: u.meter / u.s, wavelength: u.m) -> u.terahertz: return speed / wavelength frequency(speed=300_000 * u.km / u.s, wavelength=555 * u.nm)# output: 540.5405405405404 THz, frequency of green visible light

如果你需要用Python处理表格类型的科学数据,你可以尝试astropy包,体验一下计量单位随意转换的方便性。你还可以针对某个应用专门定义一个装饰器,用同样的方式来控制或转换输入和输出的计量单位。

通过 @ 实现矩阵乘法

下面,我们实现一个最简单的机器学习模型,即带 L2 正则化的线性回归 (如岭回归模型),来对比 Python2 和 Python3 之间的差别:

# l2-regularized linear regression: || AX - b ||^2 + alpha * ||x||^2 -> min# Python 2X = np.linalg.inv(np.dot(A.T, A) + alpha * np.eye(A.shape[1])).dot(A.T.dot(b))# Python 3X = np.linalg.inv(A.T @ A + alpha * np.eye(A.shape[1])) @ (A.T @ b

在 Python3 中,以@作为矩阵乘法符号使得代码整体的可读性更强,且更容易在不同的深度学习框架间进行转译:因为一些代码如 X @ W + b[None, :]在 numpy、cupy、pytorch 和 tensorflow 等不同库中都表示单层感知机。

使用 ** 作为通配符

Python2 中使用递归文件夹的通配符并不是很方便,因此可以通过定制的 glob2 模块来解决这个问题。递归 flag 在 Python 3.6 中得到了支持。

import glob# Python 2found_images = \ glob.glob('/path*.jpg') \ + glob.glob('/path*.jpg') \ + glob.glob('/path***.jpg') # Python 3found_images = glob.glob('/path*.jpg', recursive=True)

Python3 中更好的选择是使用 pathlib:(缺少个import)

# Python 3found_images = pathlib.Path('/path/').glob('**/*.jpg')

Python3中的print函数

诚然,print 在 Python3 中是一个函数,使用 print 需要加上圆括弧(),虽然这是个麻烦的操作,但它还是具有一些优点:

使用文件描述符的简单句法:

print >>sys.stderr, "critical error" # Python 2print("critical error", file=sys.stderr) # Python 3

在不使用str.join情况下能够输出 tab-aligned 表格:

# Python 3print(*array, sep='\t')print(batch, epoch, loss, accuracy, time, sep='\t')

修改与重新定义 print 函数的输出:

# Python 3_print = print # store the original print functiondef print(*args, **kargs): pass # do something useful, e.g. store output to some file

在 Jupyter notebook 中,这种形式能够记录每一个独立的文档输出,并在出现错误的时候追踪到报错的文档。这能方便我们快速定位并解决错误信息。因此我们可以重写 print 函数。

在下面的代码中,我们可以使用上下文管理器来重写 print 函数的行为:

@contextlib.contextmanagerdef replace_print(): import builtins _print = print # saving old print function # or use some other function here builtins.print = lambda *args, **kwargs: _print('new printing', *args, **kwargs) yield builtins.print = _printwith replace_print():

但是,重写print函数的行为,我们并不推荐,因为它会引起系统的不稳定。

print函数可以结合列表生成器或其它语言结构一起使用。

# Python 3result = process(x) if is_valid(x) else print('invalid item: ', x)

f-strings 可作为简单和可靠的格式化

默认的格式化系统提供了一些灵活性操作。但在数据实验中这些操作不仅不是必须的,还会导致代码的修改变得冗长和琐碎。

而数据科学通常需要以固定的格式,迭代地打印出一些日志信息,所使用的代码如下:

# Python 2print('{batch:3} {epoch:3} / {total_epochs:3} accuracy: {acc_mean:0.4f}±{acc_std:0.4f} time: {avg_time:3.2f}'.format( batch=batch, epoch=epoch, total_epochs=total_epochs, acc_mean=numpy.mean(accuracies), acc_std=numpy.std(accuracies), avg_time=time / len(data_batch) ))# Python 2 (too error-prone during fast modifications, please avoid):print('{:3} {:3} / {:3} accuracy: {:0.4f}±{:0.4f} time: {:3.2f}'.format( batch, epoch, total_epochs, numpy.mean(accuracies), numpy.std(accuracies), time / len(data_batch) ))

样本输出为:

120 12 / 300 accuracy: 0.8180±0.4649 time: 56.60

Python 3.6 中引入了格式化字符串 (f-strings):

f# Python 3.6+print(f'{batch:3} {epoch:3} / {total_epochs:3} accuracy: {numpy.mean(accuracies):0.4f}±{numpy.std(accuracies):0.4f} time: {time / len(data_batch):3.2f}')

另外,这对于查询语句的书写也是非常方便的:

query = f"INSERT INTO STATION VALUES (13, '{city}', '{state}', {latitude}, {longitude})"

「true pision」和「integer pision」之间的明显区别

虽然说对于系统编程来说,Python3所提供的改进还远远不够,但这些便利对于数据科学来说已经足够。

data = pandas.read_csv('timing.csv') velocity = data['distance'] / data['time']

Python 2 中的结果依赖于『时间』和『距离』(例如,以米和秒为单位),关注其是否被保存为整数。

而在 Python 3 中,结果的表示都是精确的,因为除法运算得到的都是精确的浮点数。

另一个例子是整数除法,现在已经作为明确的运算:

n_gifts = money // gift_price # correct for int and float arguments

值得注意的是,整除运算可以应用到Python的内建类型和由numpy、pandas等数据包提供的自定义类型。

严格排序

下面是一个严格排序的例子:

# All these comparisons are illegal in Python 33 < '3'2 < None(3, 4) < (3, None)(4, 5) < [4, 5]# False in both Python 2 and Python 3(4, 5) == [4, 5]

严格排序的主要功能有:

防止不同类型实例之间的偶然性排序。

sorted([2, '1', 3]) # invalid for Python 3, in Python 2 returns [2, 3, '1']

在处理原始数据时帮助我们发现存在的问题。此外,严格排序对None值的合适性检查是(这对于两个版本的 Python 都适用):

if a is not None: passif a: # WRONG check for None pass

自然语言处理中的Unicode编码

下面来看一个自然语言处理任务:

s = '您好'print(len(s))print(s[:2])

比较两个版本Python的输出:

Python2: 6\n

Python3: 2\n 您好

再来看个例子:

x = u'со' x += 'co' # ok x += 'со' # fail

在这里,Python 2 会报错,而 Python 3 能够正常工作。因为我在字符串中使用了俄文字母,对于Python2 是无法识别或编码这样的字符。

Python 3 中的 strs 是 Unicode 字符串,这对非英语文本的自然语言处理任务来说将更加地方便。还有些其它有趣的应用,例如:

'a'< type < u'a' # Python 2: True'a' < u'a' # Python 2: False

from collections import Counter Counter('Mbelstück')

Python 2: Counter({'\xc3': 2, 'b': 1, 'e': 1, 'c': 1, 'k': 1, 'M': 1, 'l': 1, 's': 1, 't': 1, '\xb6': 1, '\xbc': 1})

Python 3: Counter({'M': 1, '': 1, 'b': 1, 'e': 1, 'l': 1, 's': 1, 't': 1, 'ü': 1, 'c': 1, 'k': 1})

对于这些,Python 2 也能正常地工作,但 Python 3 的支持更为友好。

保留词典和**kwargs 的顺序

CPython 3.6+ 的版本中字典的默认行为是一种类似 OrderedDict 的类,但最新的 Python3.7 版本,此类已经得到了全面的支持。这就要求在字典理解、json 序列化/反序列化等操作中保持字典原先的顺序。

下面来看个例子:

import json x = {str(i):i for i in range(5)} json.loads(json.dumps(x))# Python 2{u'1': 1, u'0': 0, u'3': 3, u'2': 2, u'4': 4}# Python 3{'0': 0, '1': 1, '2': 2, '3': 3, '4': 4}

这种保顺性同样适用于 Python3.6 版本中的 **kwargs:它们的顺序就像参数中显示的那样。当设计数据流程时,参数的顺序至关重要。

以前,我们必须以这样繁琐的方式来编写:

from torch import nn # Python 2 model = nn.Sequential(OrderedDict([ ('conv1', nn.Conv2d(1,20,5)), ('relu1', nn.ReLU()), ('conv2', nn.Conv2d(20,64,5)), ('relu2', nn.ReLU()) ])) # Python 3.6+, how it *can* be done, not supported right now in pytorch model = nn.Sequential( conv1=nn.Conv2d(1,20,5), relu1=nn.ReLU(), conv2=nn.Conv2d(20,64,5), relu2=nn.ReLU()) )

注意到了吗?名称的唯一性也会被自动检查。

迭代拆封

Python3 中引入迭代式拆封功能,下面来看一段代码:

# handy when amount of additional stored info may vary between experiments, but the same code can be used in all casesmodel_paramteres, optimizer_parameters, *other_params = load(checkpoint_name)# picking two last values from a sequence*prev, next_to_last, last = values_history# This also works with any iterables, so if you have a function that yields e.g. qualities,# below is a simple way to take only last two values from a list *prev, next_to_last, last = iter_train(args)

默认的 pickle 引擎为数组提供更好的压缩

Python3 中引入 pickle 引擎,为数组提供更好的压缩,节省参数空间:

# Python 2import cPickle as pickleimport numpyprint len(pickle.dumps(numpy.random.normal(size=[1000, 1000])))# result: 23691675# Python 3import pickleimport numpylen(pickle.dumps(numpy.random.normal(size=[1000, 1000])))# result: 8000162

这个小的改进节省了3倍的空间,而且运行阶段速度更快。实际上,如果不关心速度的话,类似的压缩性能也可以通过设置参数 protocol=2 来实现,但是用户经常会忽略这个选项或者...

img

在线咨询

建站在线咨询

img

微信咨询

扫一扫添加
动力姐姐微信

img
img

TOP