参考来源:Vitu.AI
在这节课里,让我们来认识一下python最棒的地方之一(特别是如果你是或者想成为一个数据科学家的话),即拥有大量高质量的自定义库。
让我们一起来了解一下python中的导入(import),给出一些使用不熟悉的库(以及它们返回的对象)的技巧,并初步意识到操作符重载这一python的核心部分。
Import
一些库位于“标准库”中,这意味着我们可以在运行python的任何地方找到它们,而其他库,虽然python不直接提供,但是我们可以很容易地通过import添加。
让我们先来看一下,如何从标准库导出我们想要的库:
import math
print("It's math! It has type {}".format(type(math)))
是的,math是一个模块(module)。模块是由一系列的值和变量组成的,我们可以使用内置函数dir()看到math中所有的变量名称:
dir(math)
在pyhton的语法中,我们可以使用小圆点(·)来调用这些变量。其中一些直接引用简单的值,如:
math.pi
让我们结合str.format来做一个有趣的尝试:
print("pi to 4 significant digits = {:.4}".format(math.pi))
在math这一模块中,除了值,更多的还是函数,比如:
math.log(32, 2)
当然,如果我们不知道math.log()是做什么的,我们可以调用help()来寻找答案:
help(math.log)
我们还可以对模块本身调用help()。
这将为我们提供一个模块中所有函数和值的组合文档(以及模块的具体描述)。
让我们来看看python是如何描述模块math:
help(math)
import的其他语法
如果我们知道我们将经常使用模块math中的函数,我们可以在导入这个模块时,给它一个较短的别名下以节省一些输入。
尽管“math”已经很短了,但是我们还会在接下来的课程里遇到其他的库,比如说pandas,numpy,tensorflow和matplotlib等金融分析师和数据科学家常用的。
import math as mt
mt.pi
as可以帮助我们在导入模块的时候重新命名这个模块,比如:
# 我们通常约定俗成,将以下的模块这样命名:
import numpy as ny
import pandas as pd
除了as,我们还可以这样做:
import math
mt = math
mt.pi
即使使用了模块较短的别名,每次调用函数时,我们还是要告诉python,这个函数属于哪个模块。
那么有没有办法可以让我们直接调用函数呢?我们是否可以直接调用pi,而不需要通过math.pi的方式呢?
让我们一起来看一看如何解决这个问题:
from math import *
print(pi)
print(log(32, 2))
import *
可以让我们直接调用该模块里的所有变量和值 (不带任何虚线前缀的变量)。
但是,这个不是所有时候都通用。
from math import *
from numpy import *
print(pi)
print(log(32, 2))
这是怎么回事呢?为什么python突然出错了呢?
这种import *
有时会导致这样的奇怪而又难以调试的情况发生。上述代码的问题是math和numpy模块都有一个名为log的函数,但它们有不同的语义。因为我们是后从numpy中导入log的,它会覆盖掉我们从math导入的log变量。
一个很好的折衷方案是只从每个模块导入我们需要的特定内容:
from math import log, pi
from numpy import asarray
print(pi)
print(log(32, 2))
子模块
到现在为止,我们已经看到一个模块里可以包含一系列的函数或值。
值得注意的是,一个模块里的变量也可以有指向其他模块,这样的模块我们叫做子模块(submodule)。
让我们来看个例子:
import numpy
print("numpy.random is a", type(numpy.random))
print("it contains names such as...",
dir(numpy.random)[-25:-20]
)
因此,如果我们如上所述导入numpy模块,那么调用random这一子模块(submodule
)中的函数将需要两个小圆点(numpy.random.randint()
)。
# 掷十次骰子
import numpy
rolls = numpy.random.randint(low=1, high=6, size=10)
print(rolls)
print(type(rolls))
如何了解一个库?
在上述的代码单元里,我们看到了一个新的名词ndarray。
虽然我们在本课程从未见过这样的事物,但是不要惊慌。
帮你总结一个三部曲来学习新的事物。
- type()
- dir()
- help()
让我们一一来解析以下。
第一步:type()
type()会告诉我们这个这个事物的类型:
print(type(rolls))
第二部:dir()
dir()会告诉我们,这个新事物可以有哪些使用方式:
print(dir(rolls))
# 求掷十次骰子的平均大小
rolls.mean()
# 将这一数组转换为我们熟悉的列表
rolls.tolist()
第三部:help()
help()会告诉我们更多关于这个事物的信息,包含如何使用这个事物和相关函数的具体方法:
help(rolls.mean)
运算符重载
让我们先来看一下例子:
[3, 4, 1, 2, 2, 1] + 10
是的,python当然会报错。
在上一节课中,我们已经明确了解,即使是充满魔力的加号(+),也只能连接相同类型的数值。
比如说:
- str + str
- int/float + int/float
- list + list
所以,下面的代码可以成功运行:
print(rolls + 10)
列表(list)的设计者决定不允许让列表和数字可以直接用加号来处理。
但是numpy的数组(array)采用了不同的方式,我们可以将数字添加到数组的每个元素。
让我们来看几个例子:
# 在随机掷十次骰子的情况下,哪几次掷出的数字是小于或者等于3的?
print(rolls <= 3)
xlist = [[1,2,3],[2,4,6]]
xarray = numpy.asarray(xlist)
#还记得在print()里的参数如何换行吗?
print("list = {}\narray =\n{}".format(xlist, xarray))
# 让我们来获取这个数组里第二行的最后一个元素
x[1,-1]
# 同样的方法可以让我们来获取这个列表里第二个子列表的最后一个元素吗?
# 答案是不行,python会出错
xlist[1,-1]
numpy这一模块里的ndarray类型专门用于处理多维数据,因此它定义了自己的索引逻辑,允许我们通过元组索引来指定每个维度的索引。
了解了nupmy里array的运算符重载,是不是很有趣呢?
让我们一起来看看tensorflow里的运算符重载吧,这是一个常用语机器学习的模块。
# 创建两个为1的常数值
a = tf.constant(1)
b = tf.constant(1)
# 把它们相加
print(a + b)
a+b不等于2。
根据tensorflow的帮助文档,这是一个象征性的符号,用来代表这个运算的其中一种运算结果。它不保存该操作输出的值,而是提供了在tensorflow tf.session中计算这些值的方法。
让我们来简单地看看运算符如何应用于pandas的DataFrame。
df[(df['population'] > 10**6) & (df['continent'] == 'South America')]
是不是看起来很复杂?没关系,我们在这节课里不需要明白这些。
重要的是要我们意识到不同的库对于运算符号有不同的使用方法和输出结果。
理解python的运算符在应用于int、string和list时的工作方式,并不能保证我们能够立即理解它们在应用于其他库,比如tensorflow,numpy或pandas里的工作方式。
即将启程
所以在上了七节课之后,相信现在的你已经熟悉了四种数值类型,即int、float、bools和string,三种数据结构,即list、tuple和dict,和运算符,即加号(+)和乘号(*)的使用等等。
但是我们掌握python的旅程才刚刚开始。我们还可以了解更多的相关课程,比如说,
- pandas和numpy会为我们提供强有力的数据框(Dataframe)和序列(Series)
- matplotlib会通过子图(Subplots), 图表(Figures), 刻度线(TickMarks), 和图形注解(Annotations)帮助我们如何画图
- 机器学习
- 如何把python应用到实际中
祝你好运!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。