Python Data Science Handbook

第一章 Jupyter

1.

In [1]: help(len)   
Help on built-in function len in module builtins:   
len(...)    
len(object) -> integer
Return the number of items of a sequence or mapping.

In [2]: len?
Type: builtin_function_or_method
String form: <built-in function len>
Namespace: Python builtin
Docstring:
len(object) -> integer
Return the number of items of a sequence or mapping.

2.使用??查看源码

3.%run myscript.py
可以通过%run来执行外部代码,并且执行过后就可以其中的函数和类了。

4.通过%timeit可以对函数的执行进行计时。即得到运行的函数所要使用的时间。

%timeit d=1
13.7 ns ± 0.0334 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

也可以对多步进行计时

%%timeit
...:d=1
...:s=2
19 ns ± 0.0779 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

这里要注意的是所有计时的代码在计时过后不会在内存中留下任何东西。

5.使用In和Out可以得到jupyter中的所有输入和输出。 并可以通过In[x]和Out[x]来获得指定单元格中的输入和输出。还可以通过来获得上一个输出,__代表上上个,以此类推。
若想要阻止输出,则在句尾加个分号,那么这个out便不会加入到历史中。

6.%history 可显示出所有代码执行的顺序,这十分有用。

x=3
x+=1
y=33
y+=2
%history

x=3
x+=1
y=33
y+=2
%history

%history -n 1-4 表示显示1到前四步。

7.加前缀!就代表是shell命令

!ls

jupyter与shell之间也可以相互交互。

8.使用%xmode对异常显示信息的方式进行调节
总共有三个模式,分别为Plain(简略),
Context(正常), and Verbose(复杂)。
%xmode Verbose

9.debug 模式,这个十分重要
在出现异常之后,通过%debug进入debug模式,不仅可以查看变量值,还能执行普通的python代码。并且可以输入up和down进行函数的进入和跳出。输入quit停止调试。

第二章 Numpy

1.python中的整型不只是整型,每当创建一个整型,实际上是在C中创建了一个结构体,包含了垃圾回收、长度、值、类型等等。这样的坏处是,当我们创建一个大型Python整型集合时,就会占用大量内存。

2.众所周知,python的列表中的元素的,类型可以是不一样的,因为他们每一种类型在C中都是一个结构体。但是得到极高的灵活性的同时,也损失了速度和内存。特别是当列表中的元素都是同一类型时。
因此在3.3版本之后,Python提供了固定类型数组。只需要导入array模块。

In[6]: import array
L = list(range(10))
A = array.array('i', L)
A
Out[6]: array('i', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

3.numpy中的ndarray中的元素只能拥有同一种类型。
使用array()可以将列表转化为ndarray类型,但列表中也只能包含同一类型。

In[11]: # nested lists result in multidimensional arrays
np.array([range(i, i + 3) for i in [2, 4, 6]])
Out[11]: array([[2, 3, 4],
                [4, 5, 6],
                [6, 7, 8]])

np.full((3, 5), 3.14)
Understanding Data Types in Python | 39Out[14]: array([[ 3.14, 3.14, 3.14, 3.14, 3.14],
                                                        [ 3.14, 3.14, 3.14, 3.14, 3.14],
                                                        [ 3.14, 3.14, 3.14, 3.14, 3.14]])

In[16]: # Create an array of five values evenly spaced between 0 and 1
np.linspace(0, 1, 5)
Out[16]: array([ 0. , 0.25, 0.5 , 0.75, 1. ])

In[17]: # Create a 3x3 array of uniformly distributed
# random values between 0 and 1
np.random.random((3, 3))
Out[17]: array([[ 0.99844933, 0.52183819, 0.22421193],
                [ 0.08007488, 0.45429293, 0.20941444],
                [ 0.14360941, 0.96910973, 0.946117 ]])

In[18]: # Create a 3x3 array of normally distributed random values
# with mean 0 and standard deviation 1
np.random.normal(0, 1, (3, 3))
Out[18]: array([[ 1.51772646, 0.39614948, -0.10634696],
                [ 0.25671348, 0.00732722, 0.37783601],
                [ 0.68446945, 0.15926039, -0.70744073]])

In[19]: # Create a 3x3 array of random integers in the interval [0, 10)
np.random.randint(0, 10, (3, 3))
Out[19]: array([[2, 3, 4],
[5, 7, 8],
[0, 5, 0]])
In[20]: # Create a 3x3 identity matrix
np.eye(3)
Out[20]: array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
In[21]: # Create an uninitialized array of three integers
# The values will be whatever happens to already exist at that
# memory location
np.empty(3)
Out[21]: array([ 1., 1., 1.])

4.ndarray的切片返回的是view,reshape()在一般情况下(内存相邻)返回的也是view。
在reshape到两个维度的情况下,可以使用newaxis关键字。

5.ndarray的分割与结合,结合使用concatenation和stack、vstack、hstack函数,分离使用split、vsplit、hsplit函数。

In[50]: x = [1, 2, 3, 99, 99, 3, 2, 1]
x1, x2, x3 = np.split(x, [3, 5])
print(x1, x2, x3)
[1 2 3] [99 99] [3 2 1]
In[51]: grid = np.arange(16).reshape((4, 4))
grid
Out[51]: array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
In[52]: upper, lower = np.vsplit(grid, [2])
print(upper)
print(lower)
[[0 1 2 3]
[4 5 6 7]]
The Basics of NumPy Arrays | 49[[ 8 9 10 11]
[12 13 14 15]]
In[53]: left, right = np.hsplit(grid, [2])
print(left)
print(right)
[[ 0 1]
[ 4 5]
[ 8 9]
[12 13]]
[[ 2 3]
[ 6 7]
[10 11]
[14 15]]

6.当Python 面对十分庞大的数组操作时,实际上是非常非常慢的,因为它需要做许多次循环,最重要的是由于Python是动态编译的(解释型语言),因此不存在预编译,所有变量在运行之前都是不知道类型等信息的,这也就是执行大量循环缓慢的原因。
而Numpy则不存在这个问题,它通过ufuncs实现向量化操作,其速度远远超过了python的数组操作。

7.ufuncs拥有两个种类,unary ufuncs,用于处理单个输入,binary ufuncs,用于处理两个输入。实际上所有的ndarray之间的操作都属于ufuncs,只不过有些函数通过重载运算符来实现。

8.
In[26]: x = np.arange(1, 6)
np.add.reduce(x)
Out[26]: 15
通过reduce()函数来计算ufuncs的和。

In[28]: np.add.accumulate(x)
Out[28]: array([ 1, 3, 6, 10, 15])

通过accumulate()函数来得到ufuncs执行时的中间值。

import numpy as np
x=np.array([1,2,3,4])
y=np.array([5,6,7,8])
np.add.outer(x,y)

array([[ 6,  7,  8,  9],
       [ 7,  8,  9, 10],
        [ 8,  9, 10, 11],
          [ 9, 10, 11, 12]])

也可以使用outer()来得到拥有两个轴的矩阵。

9.np.sum(L) 计算庞大数据时,避免使用python内置的sum()。
np.min(big_array), np.max(big_array)同理。并且对于多维数组,可以通过axis来设置计算方式。

10.布尔矩阵,对ndarray操作得到布尔矩阵,并可通过将布尔矩阵作为index进行mask操作。

11.Fancy indexing
有多少维度便输入多少个数组,这些数组组成各个元素的下标。
也可以不输入数组,直接输入index或切片。