《Python数据科学手册》——读书笔记(一)

理解Python中的数据类型


  静态类型的语言(如C或Java)需要对每一个变量都进行明确的声明。
   动态类型的语言(如Python)可以跳过这个特殊规定。

	/*C代码*/
	int result = 0;
	for ( int i=0; i< 100; i++)
		result += i;

  同样,Python的代码实现如下

	/*Python代码*/
	result = 0
	for i in range(100):
		result += i

  注意最大的不同之处:C语言中,每个变量的数据类型被明确的声明。但是在Python中,类型是动态推断的。这意味着可以将任何类型的数据指定给任何变量



Python的列表不仅仅是一个列表

   创建一个整型值列表:

	L = list(range(10))
	print(type(L[0]))

列表里面的元素都是int类型

  创建一个字符串列表:

	L2 = [str(c) for c in L]
	print(type(L2[0]))

列表里面的元素都是str类型

Python具有动态类型特性,他也创建一个异构的列表

	L3 = [True, "2", 3.0, 4]
	print([type(item) for item in L3])

结果为[bool, str, float, int]



从Python列表创建数组

   首先导入numpy库,一般都是如下形式导入
import numpy as np

  • 可以用np.array从Python列表创建数组

    	# 整型数组
    	np.array([1, 4, 2, 5, 3])
    

    输出为array([1,4,2,5,3])

    注意:不同于Python列表,Numpy要求数组必须包含同一类型的数据。如果数据不匹配,Numpy会向上转换(如果可行)。

    这里整型被转换为浮点型

    np.array([3.14, 4, 2, 3])
    

    输出为array([3.14, 4. , 2. , 3. ])

    如果希望明确设置数组的数据类型,使用dtype关键字

    np.array([1,2,3,4], dtype='float32')
    

    输出为array([1. , 2., 3., 4.], dtype=float32)

    不同于Python列表,Numpy数组可以被指定位多维的

    # 嵌套列表构成的多维数组
    np.array([range(i, i+3) for i in [2,4,6]])
    

    输出为

    array([2, 3, 4],
    	  [4, 5, 6],
    	  [6, 7, 8])
    


从头创建数组

  面对大型数组的时候,用Numpy内置的方法较为高效

  • np.zeros()创建一个全为0的数组
    # 创建一个长度为10的数组,数组的值都是0
    np.zeros(10, dtype=int)
    
  • np.ones()创建一个全为1的数组
    # 创建一个3x5(三行五列)的浮点型数组,数组的值都是1.
    np.ones((3, 5), dtype=float)
    
  • np.full() 创建一个全为一个数(自定义)的数组
    # 创建一个3x5的浮点型数组,数组的值都是3.14
    np.full((3, 5), 3.14)
    
  • np.arange(起点, 终点, 步长) 创建一个从起点出发到终点结束,每次相差步长距离的一个数组 (就是一个等差数列,但注意的是前闭后开,是取不到终点的)
    np.arange(0, 20, 2)
    
  • np.linspace(起点,终点,元素个数) 创建一个元素个数自己设定的数组,其中的元素便为从起点到终点均匀分配的值(也是一个等差数列,步长为(终点-起点)/元素个数
    # 创建一个5个元素的数组,这5个数均匀地分配到0~1
    # 输出即为: array([0. , 0.25, 0.5, 0.75, 1.])
    np.linsapce(0, 1, 5)
    
  • np.random.random() 创建一个数组,数组元素是由0~1均匀分布的随机数组成的数组
    # 创建一个3x3的,在0~1均匀分布的随机数组成的数组
    np.random.random((3, 3))
    """
    输出为: array([[ 0.99844933, 0.52183819, 0.22421193], [ 0.08007488, 0.45429293, 0.20941444], [ 0.14360941, 0.96910973, 0.946117 ]])
    """
    
  • np.random.normal(均值, 方差, 形状) 创建一个数组,其中元素为指定均值和方差的正态分布的随机数数组
    # 创建一个3x3的,均值为0,方差为1的正态分布的随机数数组
    np.random.normal(0, 1, (3,3))
    """
    输出为: array([[ 1.51772646, 0.39614948, -0.10634696], [ 0.25671348, 0.00732722, 0.37783601], [ 0.68446945, 0.15926039, -0.70744073]])
    """
    
  • np.random.randint(起点, 终点, 形状) 创建一个形状自定的数组,其中的元素为**[起点,终点)区间的随机整型数组**
    # 创建一个3x3的、[0, 10)区间的随机整型数组
    np.random.randint(0, 10, (3, 3))
    
  • np.eye() 创建一个单位矩阵(并不一定必须是方阵(行数=列数的矩阵)
    # 创建一个3x3的单位矩阵
    np.eye(3)
    

   这里我只记录了书上出现的部分函数



Numpy标准数据类型

  • 可以用一个字符串来指定数据类型
    np.zeros(10, dtype='int16')
  • 可以用相关的numpy对象来指定
    np.zeros(10, dtype=np.int16)

   Numpy标准数据类型

数据类型描述
bool_布尔值(真、True 或假、False),用一个字节存储
int_默认整型(类似于 C 语言中的 long,通常情况下是 int64 或 int32)
intc同 C 语言的 int 相同(通常是 int32 或 int64)
intp用作索引的整型(和 C 语言的 ssize_t 相同,通常情况下是 int32 或 int64)
int8字节(byte,范围从–128 到 127)
int16整型(范围从–32768 到 32767)
int32整型(范围从–2147483648 到 2147483647)
int64整型(范围从–9223372036854775808 到 9223372036854775807)
uint8无符号整型(范围从 0 到 255)
uint16无符号整型(范围从 0 到 65535)
uint32无符号整型(范围从 0 到 4294967295)
uint32无符号整型(范围从 0 到 4294967295)
uint64无符号整型(范围从 0 到 18446744073709551615)
float_float64 的简化形式
float16半精度浮点型:符号比特位,5 比特位指数(exponent),10 比特位尾数 (mantissa)
float32单精度浮点型:符号比特位,8 比特位指数,23 比特位尾数
float64双精度浮点型:符号比特位,11 比特位指数,52 比特位尾数
complex_complex128 的简化形式
complex64复数,由两个 32 位浮点数表示
complex128复数,由两个 64 位浮点数表示


Numpy数组基础


Numpy数组的属性

我们将用Numpy的随机数生成器设置一组种子值,以确保每次程序执行时都可以生成同样的随机数组

import numpy as np
np.random.seed(0)     # 设置随机数种子
 
x1 = np.random.randint(10, size=6)  # 一维数组(生成[0,10)的随机数)
x2 = np.random.randint(10, size=(3,4))  # 二维数组
x3 = np.random.randint(10, size=(3,4,5))  # 三维数组

每个数组都有nidm(数组的维度),shape(数组每个维度的大小),size(数组的总大小)属性

print("x3 ndim: ", x3.ndim)
print("x3 shape: ", x3.shape)
print("x3 size: ", x3.size)

"""输出:
x3 ndim: 3  -> 三维数组
x3 shape: (3, 4, 5)
x3 size: 60 -> 3*4*5-60个元素
"""

dtype也是一个重要的属性,它是数组的数据类型

print("dtype: ", x3.dtype)

"""输出
dtype: int64
"""

itemsize表示每个数组元素字节大小
nbytes表示数组总字节大小的属性

print("itemsize: ", x3.itemsize, "bytes")
print("nbytes: ", x3.nbytes, "bytes")

"""输出
itemsize: 8 bytes
nbytes: 480 bytes
"""

一般可以认为nbytes跟itemsize和size的乘积大小相等



数组索引:获取单个元素

在一维数组中,通过中括号指定索引获取第i个值(从0开始计数)

  list[i]数组list中获取第i个元素

为了获取数组的末尾索引,可以用负值索引。最后一个元素的索引为-1,然后依次向前索引逐渐变小(-2,-3,…)

在多维数组中,可以用逗号分隔的索引元组来获取元素
  list[x, y]数组list中获取第x行,第y列的元素

同样,可以用上面获取元素的方法来修改相应位置的元素值
  list[x, y] = value 将list中的第x行第y列的值改成value
如果在一个整型的数组,企图修改里面的一个值变为浮点数,那么你输入的浮点数将会先变成整型在修改



数组切片:获取子数组

之前是用中括号来获取单个数组元素,但是我们用冒号(:)来进行切片
x[start:stop:step]
如果以上3个参数都未指定,那么它们会被分别设置默认值start=0,stop=维度的大小(size of dimension) 和 step = 1

  • 一维子数组

    x = np.arange(10)
    """输出: array([0,1,2,3,4,5,6,7,8,9])"""
    
    x[:5]  # 前5个元素
    """输出: array([0,1,2,3,4])"""
    
    x[5:] # 索引为5之后的元素
    """输出: array([5,6,7,8,9])"""
    
    x[4:7] # 中间索引从4到7之间的元素(左闭右开)
    """输出: array([4,5,6]) """
    
    x[::2] # 每隔1个元素(隔step-1个元素)
    """输出: array([0, 2, 4, 6, 8])"""
    
    x[1::2]  # 从索引1开始,每隔一个元素
    """输出: array([1, 3, 5, 7, 9])"""
    
    x[::-1]  # 从后往前依次输出
    """输出: array([9,8,7,6,5,4,3,2,1,0])"""
    
    x[5::-2] # 从索引5开始向前每隔一个元素
    """输出: array([5,3,1])"""
    
  • 多维子数组

    x2 = array([12, 5, 2, 4],
    			[7, 6, 8, 8],
    			[1, 6, 7, 7])
    
    x2[:2, :3]  # 前两行,前三列
    """输出: 
     	array([[12, 5, 2],
     			[7, 6, 8]])
     """
    
    x2[:2, ::2] # 前三行,每隔一列
    """输出
    	array([[12, 2],
    			[7, 8],
    			[1, 7]])
    """
    
    # 将矩阵左右交换,上下交换
    x2[::-1, ::-1]  # 行颠倒,列颠倒
    """输出
    	array([7, 7, 6, 1],
    			[8, 8, 6, 7],
    			[4, 2, 5, 12])
    """
    
  • 获取数组的行和列
    一种常见的需求是获取数组的单行和单列。通过将索引与切片组合起来实现这个功能。

    print(x2[:, 0])  # x2的第一列
    print(x2[0, :])  # x2的第一行
    

    在获取行时,也可以写成print(x2[0])
    list[:,i] 获取list中的第i列
    list[i,:] 获取list中的第i行

  • 创建数组的副本
    可以使用.copy()来进行赋值数组

    x2_sub_copy = x2[:2, :2].copy()
    print(x2_sub_copy)
    

    当我们对x2_sub_copy这个子数组进行修改时,原始的数组是不会发生改变的。



数组的变形

数组变形最灵活的实现方式是通过reshape()函数来实现。

grid = np.arange(1, 10).reshape((3, 3))
print(grid)

"""输出:
[[1 2 3]
 [4 5 6]
 [7 8 9]]
"""

另外一种常见的变形模式是将一个一维数组转变为二维的行或列的矩阵。可以通过reshape方法来实现,或者更简单地在一个切片操作中利用newaxis关键字。

x = np.array([1,2,3])

# 通过变形获得行向量
x.reshape((1,3))

# 通过newaxis获得的行向量
x[np.newaxis, :]
""" 结果和上面相同 """

x.reshape((3,1))
x[:, np.newaxis]
""" 结果相同 """


数组拼接和分类

  • 数组的拼接
    连接或连接Numpy中的两个数组主要由np.concatenate, np.vstacknp.hstack 来进行实现

    • np.concatenate将数组元组或数组列表作为第一个参数
        x = np.array([1, 2, 3])
        y = np.array([3, 2, 1])
        np.concatenate([x, y])
        """输出:
        array([1, 2, 3, 3, 2, 1])
        """
      
      当然也可以一次性拼接两个以上数组
      z = [99, 99, 99]
      print(np.concatenate([x, y, z]))
      """输出:
      [1 2 3 3 2 1 99 99 99]
      """
      

      np.concatenate也可以用于二维数组的拼接
    		grid = np.array([[1, 2, 3],
    						[4, 5, 6]])
    		# 沿着第一个轴拼接
    		np.concatenate([grid, grid])
    		"""输出:
    		array([[1, 2, 3],
    				[4, 5, 6],
    				[1, 2, 3],
    				[4, 5, 6]])
    		"""
    
    		# 沿着第二个轴拼接(从0开始索引)
    		np.concatenate([grid, grid], axis=1)
    		"""输出:
    		array([1, 2, 3, 1, 2, 3],
    				[4, 5, 6, 4, 5, 6])
    		"""
    
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值