Data Analysis Python

本文深入探讨了Python数据分析库NumPy和Pandas。介绍了NumPy的核心功能,如数组对象、性能优势、多维数组运算和广播机制。还详细讲解了Pandas的Series和DataFrame对象,包括数据读写、操作、排序、重复值处理等。通过实例展示了这两个库在数据处理中的强大能力。
摘要由CSDN通过智能技术生成

NumPy

简介

Numpy 是使用 Python 进行科学计算的基础包。它包含如下内容:

  • 一个强大的 N 维数组对象

  • 复杂的(广播)功能

  • 用于集成 C/C++ 和 Fortran 代码的工具

  • 有用的线性代数,傅里叶变换和随机数功能

除了明显的科学用途外,NumPy 还可以用作通用数据的高效多维容器。可以定义任意数据类型。这使 NumPy 能够无缝快速地与各种数据库集成

特点

  • numpy 能提供类似于 C 的数组的结构 ndarray,一维的常称为向量 vector,多维的称之为矩阵 matrix。

  • numpy 的数组(向量、矩阵)的各类运算要比 Python 里类似结构类型 list 列表运算处理速度要快很多!

Numpy 和原生 Python 的对比

语法实现对比

# 使用 Python 原生语法
import numpy as np
def python_sum(n):
    a = [i**2 for i in range(n)]
    b = [i**3 for i in range(n)]
    c = []
    for i in range(n):
        c.append(a[i] + b[i])
    return c
# Numpy 实现
def numpy_sum(n):
    a = np.arange(n) ** 2
    b = np.arange(n) ** 3
    return a+b

Numpy 的核心 array 对象

array 对象的背景

  • Numpy 的核心数据结构,就叫做 array 就是数组,array 对象可以是一维数组,也可以是多维数组;
  • Python 的 List 也可以实现相同的功能,但是 array 比 List 的优点在于性能好、包含数组元数据信息、大量的便捷函数;
  • Numpy 成为事实上的 Scipy、Pandas、Scikit-Learn、Tensorflow、PaddlePaddle 等框架的 “通用底层语言”
  • Numpy 的 array 和 Python 的 List 的一个区别,是它元素必须都是同一种数据类型,比如都是数字int类型,这也是 Numpy 高性能的一个原因;

array 本身支持的大量操作和函数

  • 直接逐元素的加减乘除等算数操作
  • 更好用的面向多维的数组索引
  • 求 sum/mean 等聚合函数
  • 线性代数函数,比如求解逆矩阵、求解方程组

array 数组属性

属性 说明
ndim 返回 int ;表示数组的维数
shape 返回 tuple ;表示数组的尺寸,对于 n 行 m 列的矩阵,形状为 (n, m)
size 返回 int ;表示数组的元素总数,等于数组形状的乘积
dtype 返回 data-type ;描述数组中元素的类型
itemsize 返回 int ;表示数组的每个元素的大小(以字节为单位)

ndim

X = np.array(
    [[1, 2, 3, 4],
    [5, 6, 7, 8]]
    )
X.ndim

# 2

shape

x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
X = np.array(
    [[1, 2, 3, 4],
    [5, 6, 7, 8]]
    )
x.shape  # (8,)
X.shape  # (2, 4)

size

x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
X = np.array(
    [[1, 2, 3, 4],
    [5, 6, 7, 8]]
    )
x.size  # 8
X.size  # 8

dtype

x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
X = np.array(
    [[1, 2, 3, 4],
    [5, 6, 7, 8]]
    )
x.dtype  # dtype('int32')
X.dtype  # dtype('int32')

创建 array

  1. 从 Python 的列表 List 和嵌套列表创建 array

    import numpy as np
    # 创建一个一维数组,也就是 Python 的单元素 List
    x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
    x
    # array([1, 2, 3, 4, 5, 6, 7, 8])
    
    # 创建一个二维数组,也就是 Python 的嵌套 List
    X = np.array(
        [[1, 2, 3, 4],
        [5, 6, 7, 8]]
    )
    X
    # array([[1, 2, 3, 4],[5, 6, 7, 8]])
    
  2. arange 函数创建

    arange([start,] stop[, step,], dtype=None)
    
    import numpy as np
    a = np.arange(15).reshape(3,5)
    a
    '''
    array([[ 0, 1, 2, 3, 4],
    	   [ 5, 6, 7, 8, 9],
    	   [10, 11, 12, 13, 14]])
    '''
    
    np.arange(2, 10, 2)
    # array([2, 4, 6, 8])
    
  3. ones 函数创建

    np.ones(shape, dtype=None, order='C')
    shape : int or tuple of ints Shape of the new array, e.g. (2, 3) or 2.
    
    np.ones(10)
    # array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
    
    np.ones((2,3))
    '''
    array([[1., 1., 1.],
    	   [1., 1., 1.]])
    '''
    
  4. ones_like 函数创建

    创建全是 1 形状相同的数组

    ones_like(a, dtype=float, order='C')
    
    x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
    X = np.array(
        [[1, 2, 3, 4],
        [5, 6, 7, 8]]
        )
        
    np.ones_like(x)  # array([1, 1, 1, 1, 1, 1, 1, 1])
    
    np.ones_like(X)
    '''
    array([[1, 1, 1, 1],
    	   [1, 1, 1, 1]])
    '''
    
  5. zeros 函数创建

    np.zeros(shape, dtype=None, order='C')
    
    np.zeros(10)
    # array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
    
    np.zeros((2,4))
    '''
    array([[0., 0., 0., 0.],
    	   [0., 0., 0., 0.]])
    '''
    
  6. zeros_like 函数创建

    创建全是 0 形状相同的数组

    zeros_like(a, dtype=float, order='C')
    
    x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
    X = np.array(
        [[1, 2, 3, 4],
        [5, 6, 7, 8]]
        )
        
    np.zeros_like(x)  # array([0, 0, 0, 0, 0, 0, 0, 0])
    
    np.zeros_like(X)
    '''
    array([[0, 0, 0, 0],
    	   [0, 0, 0, 0]])
    '''
    
  7. empty 函数创建

    empty(shape, dtype=float, order='C')
    

    注意:数据是未初始化的,里面的值可能是随机值不要用

    np.empty(10)
    # array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
    
  8. empty_like 函数创建

    empty_like(prototype, dtype=None)
    
    x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
    X = np.array(
        [[1, 2, 3, 4],
        [5, 6, 7, 8]]
        )
        
    np.empty_like(x)  # array([120,  46, 110, 100, 105, 109, 101,   0])
    
    np.empty_like(X)
    '''
    array([[0, 0, 0, 0],
     	   [0, 0, 0, 0]])
    '''
    
  9. full 函数创建

    np.full(shape, fill_value, dtype=None, order='C')
    
    np.full(10, 666)
    # array([666, 666, 666, 666, 666, 666, 666, 666, 666, 666])
    
    np.full((2,4), 333)
    '''
    array([[333, 333, 333, 333],
     	   [333, 333, 333, 333]])
    '''
    
  10. full_like 函数创建

    np.full_like(a, fill_value, dtype=None)
    
    x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
    np.full_like(x, 666)
    # array([666, 666, 666, 666, 666, 666, 666, 666])
    

随机数函数

函数 说明
seed 确定随机数生成器的种子
permutation 返回一个序列的随机排列或返回一个随机排列的范围
shuffle 对一个序列就地随机排列
rand 产生均匀分布的样本值
randint 从给定的上下限范围内随机选取整数
randn 产生正态分布 (平均值为 0;标准差为 1) 的样本值
binomial 产生二项分布的样本值
normal 产生正态 (高斯) 分布的样本值
beta 产生 Beta 分布的样本值
chisquare 产生卡方分布的样本值
gamma 产生 Gamma 分布的样本值
uniform 产生在 [0, 1) 中均匀分布的样本值
randn(d0, d1, ..., dn)
np.random.randn()
# -0.24298859935537268
np.random.randn(3)
# array([-0.630065  , -1.15991332, -0.69356883])
np.random.randn(3, 2)
'''
array([[-0.62787255, -0.01054911],
       [ 0.8695556 , -1.39004067],
       [ 0.16209569,  2.08941735]])
'''
np.random.randn(3, 2, 4)
'''
array([[[ 0.97915519, -0.04827654, -0.24805357, -1.18815335],
        [ 0.81855172,  0.531464  , -0.0455545 ,  0.7775499 ]],

   		[[-1.6144118 ,  0.11402734,  0.106872  ,  0.80540136],
   		 [-0.49410333,  0.13846393,  0.4897993 , -1.34085886]],

	    [[ 0.25693092,  0.4697215 , -1.00145574,  0.33612804],
		 [ 0.68994321,  0.17245859,  0.49834578,  1.37301829]]])
'''
print('numpy.random随机数生成')
import numpy.random as npr
x = npr.randint(0, 2, size = 100000)  # 抛硬币
print((x > 0).sum())                  # 正面的结果
print(npr.normal(size = (2, 2)))
# 正态分布随机数数组 shape = (2, 2)

'''
numpy.random随机数生成
49720
[[ 0.21193991 -1.33266635]
 [-0.71381904  0.40960239]]
'''
# 关于随机数种子
import numpy as np
np.random.seed(10)
# 如果不使用随机数种子,每次执行获得的随机数是不固定的
# 加上随机数种子,每次执行生成的随机数是一样的
t = np.random.randint(0, 20, (3, 4))
print(t)

'''
[[ 9  4 15  0]
 [17 16 17  8]
 [ 9  0 10  8]]
'''

关于分布:均匀分布:在相同的大小范围内的出现概率是等可能的,也即是随机分布,每个位置上出现的概率是随机的

更多API包括:linspace, logspace, diag, eye, randint, randn, random

通函数

NumPy 提供熟悉的数学函数,例如 sin,cos 和 exp 等。

在 NumPy 中,这些被称为 “通函数”(ufunc)。

在 NumPy 中,这些函数在数组上按元素进行运算,产生一个数组作为输出。

np.mean(data)         # 均值
np.std(data)          # 标准差
np.var(data)          # 方差
np.min(data)          # 最小值
np.max(data)          # 最大值
np.argmax(t, axis)    # 最大值的位置
np.argmin(t, axis)    # 最小值的位置
np.ptp(data)          # 极值

'''
可对某行或某列的数据统计
方法是在函数中添加一个 axis 参数
0表示每列 1表示每行
'''

多维数组运算

ndarray 对象的运算效率极高,不用编写循环,运算直接应用在元素级上。

import numpy as np
zarten_1 = np.array([[1, 2, 3],[4, 5, 6]])
zarten_2 = zarten_1 * 2
print(zarten_1)
print('\n')
ptint(zarten_2)

'''
[[1 2 3]
 [4 5 6]]
[[ 2  4  6]
 [ 8 10 12]]
'''
zarten_1 = np.array([[1, 2, 3],[4, 5, 6]])
zarten_2 = np.array([7, 8, 9])
print(zarten_1 + zarten_2)

'''
[[ 8 10 12]
 [11 13 15]]
'''
zarten_1 = np.array([[1, 2, 3],[4, 5, 6]])
zarten_2 = np.array([7, 8, 9])
print(zarten_1 > zarten_2)

'''
[[False False False]
 [True  True  True]]
'''

多维数组之间比较,会产生一个布尔类型的数组


一元运算

zarten = np.array([1, 2, 3, 4, 5])
print(np.sqrt(zarten))
print(np.sin(zarten))

# [1.         1.41421356 1.73205081 2.         2.23606798]
# [ 0.84147098  0.90929743  0.14112001 -0.7568025  -0.95892427]

请添加图片描述


二元运算

zarten_1 = np.array([1, 2, 3, 4, 88])
zarten_2 = np.array([6, 7, 8, 9, 10])
print(np.maximum(zarten_1, zarten_2))  # [ 6  7  8  9 88]
print(np.add(1,2))  # 3

请添加图片描述


集合运算

numpy 中提供一些针对一维的集合运算,如 unique 函数、in1d 函数等

unique 函数 跟 Python 中的 set 集合类似,但 unique 函数的输出结果是排好序的

zarten_1 = np.array([5, 3, 6, 5, 4, 2, 1, 2])
print(zarten_1)
print('\n')
print(np.unique(zarten_1))

'''
[5 3 6 5 4 2 1 2]
[1 2 3 4 5 6]
'''

in1d() 函数返回一个布尔型数组,用于判断一个数组的元素是否有在另一个数组内

zarten_1 = np.array([5, 3, 6, 5, 4, 2, 1, 2])
print(zarten_1)
print('\n')
print(np.in1d(zarten_1,[5, 3]))

# [5 3 6 5 4 2 1 2]
# [True  True False  True False False False False]

数组索引查询

  1. 基础索引

    一维数组和 Python 的 list 一样

    # 二维数组
    X  = np.arange(20).reshape(4,5)
    X
    '''
    array([[ 0,  1,  2,  3,  4],
    	   [ 5,  6,  7,  8,  9],
    	   [10, 11, 12, 13, 14],
    	   [15, 16, 17, 18, 19]])
    '''
    
    # 分别用行坐标、列坐标实现行列筛选
    X[0, 0]  # 0
    x[-1, 2]  # 17
    
    '''
    可以省略后续索引值,返回的数据是降低一个维度的数组
    这里的2其实是要筛选第2行
    '''
    X[2]  # array([10, 11, 12, 13, 14])
    
    # 筛选多行
    X[: -1]
    '''
    array([[ 0, 1, 2, 3, 4],
    	   [ 5, 6, 7, 8, 9],
    	   [10, 11, 12, 13, 14]])
    '''
    
    # 筛选多行 多列
    X[: 2, 2: 4]
    '''
    array([[2, 3],
    	   [7, 8]])
    '''
    
    # 筛选所有行 多列
    X[:, 2]
    '''
    array([2, 7, 12, 17])
    '''
    

    切片赋值

    x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
    X = np.array(
        [[1, 2, 3, 4],
        [5, 6, 7, 8]]
        )
    
    x[2: 4] = 666
    X[: 1, : 2] = 666
    x
    X
    
    '''
    array([1, 2, 666, 666, 5, 6, 7, 8])
    array([[666, 666, 3, 4],
     	   [  5,   6, 7, 8]])
    '''
    
  2. 神奇索引

    用整数数组进行的索引叫神奇索引

    '''一维数组'''
    x = np.arange(10)
    x  # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    x[[3, 4, 7]]  # array([3, 4, 7])
    
    # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    index = np.array([[0, 2],[1, 3]])
    x[index]
    '''
    array([[0, 2],
    	   [1, 3]])
    '''
    
    '''
    实例:获取数组中最大的前 N 个数字
    '''
    # 随机生成1到100之间的10个数字
    arr = np.random.randint(1, 100, 10)
    # array([92, 16, 12, 57,  1, 66, 26, 55, 68, 84])
    
    # arr.argsort() 会返回排序后的索引index
    # 取最大值对应的3个下标
    arr.argsort()[-3: ]  # array([8, 9, 0], dtype=int64)
    arr[arr.argsort()[-3:]]   # array([68, 84, 92])
    
    '''二维数组'''
    X = np.arange(20).reshape(4,5)
    '''
    array([[ 0,  1,  2,  3,  4],
    	   [ 5,  6,  7,  8,  9],
    	   [10, 11, 12, 13, 14],
    	   [15, 16, 17, 18, 19]])
    '''
    
    # 筛选多行,列可以省略
    X[[0, 2]]
    '''
    array([[ 0,  1,  2,  3,  4],
    	   [10, 11, 12, 13, 14]])
    '''
    
    X[[0, 2], :]
    '''
    array([[ 0,  1,  2,  3,  4],
    	   [10, 11, 12, 13, 14]])
    '''
    
    # 筛选多列,行不能省略
    X[:, [0, 2, 3]]
    '''
    array([[ 0,  2,  3],
    	   [ 5,  7,  8],
    	   [10, 12, 13],
    	   [15, 17, 18]])
    '''
    
    # 同时指定行列-列表
    # 返回的是[(0, 1), (2, 3), (3, 4)]位置的数字
    X[[0, 2, 3], [1, 3, 4]]
    '''
    array([ 1, 13, 19])
    '''
    
    # 同时指定行列列表
    # 创建一个1*2的矩阵
    X[np.array([0, 2]), np.array([1, 3])]
    X[[0, 2], [1, 3]]
    '''
    array([ 1, 13])
    '''
    
    # 创建一个2*3矩阵
    X[np.array([[0, 2, 3], [1, 2, 3]]), np.array([[0, 1, 0], [0, 2, 3]])]
    a = (np.array([[0, 2, 3], [1, 2, 3]]), np.array([[0, 1, 2], [0, 2, 3]]))
    X[a]
    '''
    array([[ 0, 11, 17],
    	   [ 5, 12, 18]])
    '''
    
  3. 布尔索引

    bool 数组可以通过直接指出保留的值(True)与舍弃的值(False),来构建输出的数组。

    bool 数组的 shape 需要与被索引的数组 shape 严格对齐

    '''一维数组'''
    x = np,arange(10)  # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    x > 5
    # array([False, False, False, False, False, False,  True,  True,  True,True])
    
    x[x > 5]  # array([6, 7, 8, 9])
    
    # 实例 把一维数组进行01化处理
    # 比如把房价数字,变成“高房价”为1;“低房价”为0
    x[x <= 5] = 0
    x[x > 5] = 1
    x  # array([0, 0, 0, 0, 0, 0, 1, 1, 1, 1])
    
    x = np.arange(10)  # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    x[x < 5] += 20
    x  # array([20, 21, 22, 23, 24,  5,  6,  7,  8,  9])
    
    '''二维数组'''
    X = np.arange(20).reshape(4, 5)
    X
    '''
    array([[ 0,  1,  2,  3,  4],
    	   [ 5,  6,  7,  8,  9],
    	   [10, 11, 12, 13, 14],
    	   [15, 16, 17, 18, 19]])
    '''
    
    X > 5
    '''
    array([[False, False, False, False, False],
    	   [False,  True,  True,  True,  True],
    	   [ True,  True,  True,  True,  True],
       	   [ True,  True,  True,  True,  True]])
    '''
    
    # X > 5 的 boolean 数组,既有行又有列
    # 因此返回的是(行,列)一维结果
    X[X > 5]  # array([ 6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
    
    a = np.arange(15).reshape(3, 5)
    a
    '''
    array([[ 0,  1,  2,  3,  4],
    	   [ 5,  6,  7,  8,  9],
    	   [10, 11, 12, 13, 14]])
    '''
    
    a[np.array([True, False, True])]
    '''
    array([[ 0,  1,  2,  3,  4],
    	   [10, 11, 12, 13, 14]])
    '''
    
    x = np.arange(30).reshape(2, 3, 5)
    x
    '''
    array([[[ 0,  1,  2,  3,  4],
    	    [ 5,  6,  7,  8,  9],
    	    [10, 11, 12, 13, 14]],
    	    
    		[[15, 16, 17, 18, 19],
    		[20, 21, 22, 23, 24],
    		[25, 26, 27, 28, 29]]])
    '''
    
    b = np.array([[True, True, False], [False, True, True]])
    x[b]
    '''
    array([[ 0,  1,  2,  3,  4],
    	   [ 5,  6,  7,  8,  9],
    	   [20, 21, 22, 23, 24],
    	   [25, 26, 27, 28, 29]])
    '''
    
    X = np.arange(20).reshape(4, 5)
    X
    '''
    array([[ 0,  1,  2,  3,  4],
    	   [ 5,  6,  7,  8,  9],
    	   [10, 11, 12, 13, 14],
    	   [15, 16, 17, 18, 19]])
    '''
    
    # 举例:怎样把第3列大于5的行筛选出来
    X[:, 3]  # array([ 3,  8, 13, 18])
    X[:, 3] > 6  # array([False,  True,  True,  True])
    
    # 这里是按照行进行的筛选
    X[X[:, 3] > 10]
    '''
    array([[10, 11, 12, 13, 14],
    	   [15, 16, 17, 18, 19]])
    '''
    

变换数组的形态 (维度)

改变维度

在对数组进行操作时,经常要改变数组的维度。

在 Numpy 中,常用 reshape 函数改变数组的 “形状” ,也就是改变数组的维度。其参数为一个正整数元组,分别指定数组在每个维度上的大小。

reshape 函数在改变原始数据的形状的同时不改变原始数据的值。如果指定的维度和数组的元素数目不吻合,则函数将抛出异常。

# 创建一维数组
arr = np.arange(12)
print('创建的一维数组为:', arr)
# 创建的一维数组为: [ 0  1  2  3  4  5  6  7  8  9 10 11]

# 设置数组的形状
print('新的一维数组为:', arr.reshape(3, 4))
'''
新的一维数组为: [[ 0  1  2  3]
			     [ 4  5  6  7]
			     [ 8  9 10 11]]
'''

# 查看数组维度
print('数组维度为:', arr.reshape(3, 4).ndim)
# 数组维度为: 2

增加维度

np.newaxis 关键字,使用索引的语法给数组添加维度

import numpy as np
arr = np.arange(5)  # [0, 1, 2, 3, 4]
arr.shape  # (5,)

arr[np.newaxis, :]  # array([[0, 1, 2, 3, 4]])
arr[np.newaxis, :].shape  # (1, 5)

arr[:, np.newaxis]
arr[:, np.newaxis].shape  # (5, 1)

np.expand_dims(arr, axis)np.newaxis 实现一样的功能, 给 arraxis 位置添加维度

arr = np.arange(5)  # [0, 1, 2, 3, 4]
arr.shape  # (5,)

np.expand_dims(arr, axis = 0)  # array([[0, 1, 2, 3, 4]])
np.expand_dims(arr, axis = 0).shape  # (1, 5)

np.expand_dims(arr, axis = 1)
np.expand_dims(arr, axis = 1).shape  # (5, 1)

np.reshape(a, newshape) 给一个维度设置为 1 完成升维


                
  • 28
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值