ch2-基本工具介绍

基本工具介绍

一、环境配置

安装miniconda3作为python环境。

如果配置了CUDA,可以安装tensorflow-gpu。

二、第三方库

数据预处理Numpy提供高效的N维数组和向量计算
Scipy依赖Numpy,提供高效数值计算,包含函数最优、数值积分等任务模块
pandas数据结构和数据分析库。包含高级数据结构和类SQL语句
数据可视化Matplotlib数据可视化库
标准模型库scikit-learn标准机器学习库,主要用于分类、回归和聚合
Statsmodels标准统计模型库,主要用于假设检验和参数置信区间分析
Spark ML分布式机器学习算法库,可在分布式集群上,如Hadoop,对大量数据建模。由Scala开发,提供python API
Tensorflow成熟的数度学习算法库,提供GPU运算模块

三、python基础知识

小技巧:

  • type得到调用对象的类型;
  • dir得到调用对象的所有属性和方法;
  • help得到模块的使用方法;也可以调用.__doc__属性;
import numpy as np

type(np)        # module
dir(np)         # 返回np的所有方法
help(np.max)    # 返回np.max的说明文档
print(np.max.__doc__) 
# 和上一条命令结果一致;一定要加print,不然格式很乱。

四、数据科学的"hello,world"

wordCount.py

def wordCount(data):
    """
    输入字符串列表data,统计列表中每个字符串的出现次数

    参数
    ----
    data : list[str]

    返回
    ----
    re : dict{key=str, value=numbers of each str}
    """
    re = {}
    for i in data:
        re[i] = re.get(i, 0) + 1
    return re

if __name__=="__main__":
    data = {‘ab‘, ‘cd‘, ‘ab‘, ‘d‘, ‘d‘}
    print(wordCount(data))

1. 脚本开头

在python2中,默认编码是ASCII,当程序出现非ASCII编码时,会报错,所以在python2脚本第一行加入:# -*- coding: UTF-8 -*- ,表示:此脚本的编码格式为UTF-8。

当程序中有中文字符,就需要加入这一行来显示中文字符。

在python3中,默认使用UTF-8编码,不需要加入这行。

还有一种开头方式较为常见:#! /usr/bin/python。在脚本第一行以#!开头,称之为"shebang",用来指定由哪个解释器来执行脚本。这句话的意思就是:此脚本的编译器要使用/usr/bin/python。

大部分Linux发行版默认自带python2,使用python默认打开的就是python2;但是在Ubuntu20.04已经移除2,需要使用python3命令启动python3.8。python2脚本为了能顺利执行,需要指定特定编译器。

我们推荐使用#! /usr/bin/env python。为了避免当用户没有将python装在默认的/usr/bin路径里,而找不到python解释器的问题。过程:操作系统首先会到usr/bin/env里查找python的安装路径,再调用对应路径下的解释器程序完成操作。这句代码的作用是让操作系统会去环境设置寻找python目录。

在Ubuntu20.04中,使用/usr/bin/env python3也能启动python3.8

2. dict.get(key, default=None)

检查字典是否包含key,如果包含则返回对应的键值,没有则返回默认值default=None。

使用dict.get()来统计data中各个字符串出现的次数,这个思路还是很不错的。

3. 模板对象

python中,所有内容都是对象。

比如函数wordCount()可以使用wordCount.__doc__查看函数的注释文档。

同样的,脚本也被当作模板(module)对象。module对象有个内置属性__name__,至于这个属性的值,取决于用户如何使用。

  • 如果直接运行脚本,那么__name__ = __main__;
  • 如果导入脚本import wordCount,那么__name__属性就等于wordCount;

五、lambda表达式和内置函数map, reduce, filter

# 函数写法
def f(a,b):
    return a+b
c=f(1,2)

# lambda表达式
g = lambda a, b: a+b
g(1,2)

lambda表达式不仅简洁,把它和其他内置函数使用,可以方便地创建匿名函数

lambda+map

def addOne(data):
    """
    把data的每个元素都加1,返回新的列表。
    """
    re=[]
    for i in data:
        re.append(i+1)

# lambda+map()完成同样的效果
a=range(6)
b = list(map(lambda x:x+1, a))

map(function, iterable, ...)第二个参数是可迭代对象,比如list, tuple和dict。用法是:把第二个参数中的每个元素依次代入function

在python3中,直接使用map()得到的是个map object,是没法直接展示结果的。所以需要强制类型转换,上面我们使用list()强制转换成了list类型,也可以用tuple强制转换成元组。

lambda也可以接受函数作为参数;

a = range(6)
twoTimes = lambda x: x*2
square = lambda x: x**2
b = list(list(map(lambda x: x(i), [twoTimes, square])) for i in a)
print(b)

这里强调一下两个list的用法。里面的list是把map->list;由于for循环在后面,所以最外面也需要加一个list组织起来。

lambda+filter/reduce

filter的用法和map很像,作用是筛选,筛选的条件是:去掉第一个函数的返回值是0的元素,也就是那些结果为False的元素。

a = range(6)
list(filter(lambda x: x%2==0, a))

reduce是用来做聚合运算的。python3中,把reduce放在了functools,使用前需要导入。

from functools import reduce
reduce(lambda c,d: c+d, a, 0)
# 返回值:15
# 第一个参数为求和函数;第二个参数是需要求和列表;第三个参数是初始值

六、python的工程结构

作用:像导入Numpy库一样,导入自己的脚本。以下面一个简单文件结构为例:

mini_project
    |_components
        counter.py  
        selecter.py 
    |_tests
        test_selecter.py
  • counter.py:定义wordCount()函数;
  • selecter.py:定义getFrequentItem()函数,调用wordCount()函数;
  • test_selecter.py:调用getFrequentItem()函数;

问题是:上面两处调用如何实现?如果按照导入库一样实现,那么实现步骤如下:

  • 在每个文件夹下加入__init__.py,这是一个空白文件,加入后python会把这个文件夹当作包识别,反之只会当作普通文件夹;新的文件夹结构如下:
mini_project
    __init__.py
    |_components
        __init__.py
        counter.py  
        selecter.py 
    |_tests
        __init__.py
        test_selecter.py
  • selecter.py的调用为from mini_project.components.counter import wordCount
  • test_selecter.py的调用为from mini_project.components.selecter import getFrequentItem
  • mini_project这个文件夹的位置添加到sys.path中;
    • 查看sys.path的方法为import sys; sys.path
    • 添加方法有三种,自行查阅。

相关推荐