7.Working with External Libraries
在本課中,我將討論Python中的imports,提供一些使用不熟悉的庫(以及它們返回的對象)的技巧,并深入研究Python的內容,以及談談運算符重載。
Imports
到目前為止,我們已經討論了內置于該語言的類型和函數。
但是關于Python的最好的事情之一(特別的如果你是一名數據科學家)是為它編寫的大量高質量自定義庫。
其中一些庫位于“標準庫”中,這意味著您可以在運行Python的任何位置找到它們。 其他庫可以輕松添加,即使它們并不總是隨Python一起提供。
無論哪種方式,我們都會使用導入訪問此代碼。
我們將從標準庫中導入math開始我們的示例。
【1】
import mathprint("It's math! It has type {}".format(type(math))) It's math! It has type <class 'module'>math是一個模塊,模塊只是其他人定義的變量集合。 我們可以使用內置函數dir()查看數學中的所有名稱。
【2】
print(dir(math)) ['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']我們可以使用點語法訪問這些變量。 其中一些是指簡單的值,比如math.pi:
【3】
print("pi to 4 significant digits = {:.4}".format(math.pi)) pi to 4 significant digits = 3.142但是我們在模塊中找到最多的是函數:像math.log:
[4]
math.log(32, 2) 5.0當然,如果我們不了解math.log做什么,我們調用help()函數:
【5】
help(math.log) Help on built-in function log in module math:log(...)log(x[, base])Return the logarithm of x to the given base.If the base not specified, returns the natural logarithm (base e) of x.我們也可以在模塊本身上調用help()。 這將為我們提供模塊中所有函數和值的組合文檔(以及模塊的高級描述)。?
【6】
help(math)Other import syntax
如果我們知道我們將經常使用math中的函數,我們可以在較短的別名下導入它以節省一些輸入(盡管在這種情況下“math”已經相當短)。
【7】
import math as mt mt.pi 3.141592653589793您可能已經看到了使用某些流行的庫(如Pandas,Numpy,Tensorflow或Matplotlib)執行此操作的代碼。 例如,import numpy as np 和 import pandas as pd是一種常見的約定。
as相當于重命名導入模塊,等價于如下操作:
[8]
import math mt = math如果我們可以自己引用數學模塊中的所有變量,那不是很好嗎? 即如果我們可以只引用pi而不是math.pi或mt.pi? 好消息:我們可以做到這一點。
[9]
from math import * print(pi, log(32, 2)) 3.141592653589793 5.0import *使您可以直接訪問所有模塊的變量。
壞消息:一些純粹主義者可能會抱怨你這樣做。
[10]
什么是什么? 但它以前工作過!
這些“star imports”偶爾會導致奇怪的,難以調試的情況。
這種情況下的問題是math和numpy模塊都有稱為log的函數,但它們具有不同的語義。 因為numpy導入在第二個,覆蓋了我們從math導入的變量。
一個很好的折衷方案是只從每個模塊導入我們需要的特定內容:
[11]
from math import log, pi from numpy import asarraySubmodules
我們已經看到模塊包含可以引用函數或值的變量。 需要注意的是,它們也可以包含引用其他模塊的變量。
[12]
import numpy print("numpy.random is a", type(numpy.random)) print("it contains names such as...",dir(numpy.random)[-15:]) numpy.random is a <class 'module'> it contains names such as... ['set_state', 'shuffle', 'standard_cauchy', 'standard_exponential', 'standard_gamma', 'standard_normal', 'standard_t', 'test', 'triangular', 'uniform', 'vonmises', 'wald', 'warnings', 'weibull', 'zipf']如果我們導入numpy模塊,調用randon子模塊中的函數需要兩個點號。
【13】
# Roll 10 dice rolls = numpy.random.randint(low=1, high=6, size=10) rolls array([2, 1, 5, 2, 4, 5, 4, 5, 5, 5])Oh the places you'll go, oh the objects you'll see
所以在經過6課之后,你對 整數,浮點數,布爾,列表,字符串和字典很熟悉了(對吧?)。
即使這是真的,也不會就此結束。 當您使用各種庫進行專門任務時,您會發現他們定義了您自己必須學習使用的類型。 例如,如果您使用圖形庫matplotlib,您將接觸到它定義的對象,這些對象代表子圖,數字,TickMark和注釋。 pandas函數將為您提供DataFrames和Series。
在本節中,我想與您分享一個快速生存指南,用于處理奇怪的類型。
Three tools for understanding strange objects
在上面的例子中,我們看到調用一個numpy函數給了我們一個“數組”。 我們以前從未見過這樣的事情(不管怎么說都不是這樣)。 但不要驚慌:我們有三個熟悉的內置函數來幫助我們。
1:type()(這是什么東西?)
【14】
type(rolls)numpy.ndarray2.dir()(我可以用它做什么?)
【15】
print(dir(rolls)) ['T', '__abs__', '__add__', '__and__', '__array__', '__array_finalize__', '__array_interface__', '__array_prepare__', '__array_priority__', '__array_struct__', '__array_ufunc__', '__array_wrap__', '__bool__', '__class__', '__complex__', '__contains__', '__copy__', '__deepcopy__', '__delattr__', '__delitem__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__iand__', '__ifloordiv__', '__ilshift__', '__imatmul__', '__imod__', '__imul__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__ior__', '__ipow__', '__irshift__', '__isub__', '__iter__', '__itruediv__', '__ixor__', '__le__', '__len__', '__lshift__', '__lt__', '__matmul__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmatmul__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__setitem__', '__setstate__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__xor__', 'all', 'any', 'argmax', 'argmin', 'argpartition', 'argsort', 'astype', 'base', 'byteswap', 'choose', 'clip', 'compress', 'conj', 'conjugate', 'copy', 'ctypes', 'cumprod', 'cumsum', 'data', 'diagonal', 'dot', 'dtype', 'dump', 'dumps', 'fill', 'flags', 'flat', 'flatten', 'getfield', 'imag', 'item', 'itemset', 'itemsize', 'max', 'mean', 'min', 'nbytes', 'ndim', 'newbyteorder', 'nonzero', 'partition', 'prod', 'ptp', 'put', 'ravel', 'real', 'repeat', 'reshape', 'resize', 'round', 'searchsorted', 'setfield', 'setflags', 'shape', 'size', 'sort', 'squeeze', 'std', 'strides', 'sum', 'swapaxes', 'take', 'tobytes', 'tofile', 'tolist', 'tostring', 'trace', 'transpose', 'var', 'view']【16】
# What am I trying to do with this dice roll data? Maybe I want the average roll, in which case the "mean" # method looks promising... rolls.mean() 3.8【17】
# Or maybe I just want to get back on familiar ground, in which case I might want to check out "tolist" rolls.tolist() [2, 1, 5, 2, 4, 5, 4, 5, 5, 5]3.help()(告訴我更多)
【18】
# That "ravel" attribute sounds interesting. I'm a big classical music fan. help(rolls.ravel)Help on built-in function ravel:ravel(...) method of numpy.ndarray instancea.ravel([order])Return a flattened array.Refer to `numpy.ravel` for full documentation.See Also--------numpy.ravel : equivalent functionndarray.flat : a flat iterator on the array.【19】
# Okay, just tell me everything there is to know about numpy.ndarray # (Click the "output" button to see the novel-length output) help(rolls)當然,你可能更喜歡查看在線文檔。
Operator overloading
下面表達式的值是多少?
【20】
[3, 4, 1, 2, 2, 1] + 10 --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-20-1b8555d93650> in <module>() ----> 1 [3, 4, 1, 2, 2, 1] + 10TypeError: can only concatenate list (not "int") to list多么愚蠢的問題,當然會報錯。
但是。。。
【21】
rolls + 10array([12, 11, 15, 12, 14, 15, 14, 15, 15, 15])我們可能會認為Python嚴格控制其核心語法的行為,例如+,<,in,==或方括號用于索引和切片。 但事實上,它需要一種非常不干涉的方法。 定義新類型時,可以選擇添加的工作方式,或者該類型的對象與其他對象的含義相同。
列表的設計者決定不允許將它們添加到數字中。 numpy數組的設計者采用了不同的方式(將數字添加到數組的每個元素)。
下面是一些numpy數組如何與Python運算符交互(或者至少與列表不同)的示例。
【22】
# At which indices are the dice less than or equal to 3? rolls <= 3 array([ True, True, False, True, False, False, False, False, False,False])【23】
xlist = [[1,2,3],[2,4,6],] # Create a 2-dimensional array x = numpy.asarray(xlist) print("xlist = {}\nx =\n{}".format(xlist, x))xlist = [[1, 2, 3], [2, 4, 6]] x = [[1 2 3][2 4 6]]【24】
# Get the last element of the second row of our numpy array x[1,-1]6【25】
# Get the last element of the second sublist of our nested list? xlist[1,-1]--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-25-f74d164f666a> in <module>()1 # Get the last element of the second sublist of our nested list? ----> 2 xlist[1,-1]TypeError: list indices must be integers or slices, not tuplenumpy的ndarray類型專門用于處理多維數據,因此它定義了自己的索引邏輯,允許我們通過元組來指定每個維度的索引。
1 + 1何時不等于2?
事情可能比這更奇怪。 您可能聽說過(甚至使用過)tensorflow,這是一種廣泛用于深度學習的Python庫。 它廣泛使用了運算符重載。
【26】
import tensorflow as tf # Create two constants, each with value 1 a = tf.constant(1) b = tf.constant(1) # Add them together to get... a + b <tf.Tensor 'add:0' shape=() dtype=int32>a + b不是2,它是(引用tensorflow的文檔)......
???? 操作的一個輸出的符號句柄。 它不保存該操作的輸出值,而是提供在TensorFlow tf.Session中計算這些值的方法。
重要的是要意識到這樣的事情是可能的,并且庫通常會以非顯而易見或神奇的方式使用運算符重載。
理解Python的運算符在應用于整數,字符串和列表時的工作原理并不能保證您在應用與tensorflow Tensor,numpy ndarray或pandas DataFrame時能夠立即理解它們的作用。
例如,一旦您對DataFrame有一點興趣,下面的表達式開始看起來很吸引人:
但為什么它有效呢? 上面的例子有5個不同的重載運算符。 這些操作中的每一項都在做什么? 當事情開始出錯時,它可以幫助你知道答案。
很好奇這些是怎么工作的?
你有沒有在一個對象上調用help()或dir(),并想知道所有帶有雙下劃線的名字到底是什么?
【27】
print(dir(list))['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']結果與運算符重載直接相關。
當Python程序員想要定義操作符在其類型上的行為方式時,他們通過實現具有特殊名稱的方法來實現,這些特征名稱以2個下劃線開頭和結尾,例如__lt __,__ setattr __或__contains__。 通常,遵循此雙下劃線格式的名稱對Python具有特殊含義。
因此,例如,[1,2,3]中的表達式x實際上是在幕后調用list方法__contains__。 它相當于(更加丑陋)[1,2,3] .__包含__(x)。
如果您想了解更多信息,可以查看Python的官方文檔,其中描述了許多這些特殊的“下劃線”方法。
我們不會在這些課程中定義我們自己的類型,但我希望你能夠體驗到后來定義你自己的奇妙,怪異類型的樂趣。
Your turn!
轉到最后一個練習筆記本,再進行一輪涉及導入庫,處理不熟悉的對象,當然還有更多的賭博的編程問題。
?
總結
以上是生活随笔為你收集整理的7.Working with External Libraries的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《龙族》动画定档预告公开:8月19日腾讯
- 下一篇: Apoll进阶课程㉞丨Apollo RO