【Python爬虫与数据分析】NumPy进阶——数组操作与运算

目录

一、NumPy数组操作

1. ndarray更改形状

2. ndarray转置

3. ndarray组合

4. ndarray拆分

5. ndarray排序

二、NumPy数组运算

1. 基本运算

2. 逻辑函数

3. 数学函数

三、日期时间的表示和间隔

1. 日期时间的表示——datetime64

2. 日期时间的计算——timedelta64

3. datetime64与datetime的转换


一、NumPy数组操作

1. ndarray更改形状

在对数组进行操作时,为了满足格式和计算的要求通常会改变其形状。
numpy.ndarray.shape 表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即 ndim属性(秩)。

shape:通过列表和元组重定义数组形状

import numpy as np

a1 = np.arange(12)
a1
# array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

a1.shape
# (12,)

a1.shape = [3, 4]
a1
# array([[ 0,  1,  2,  3],
#        [ 4,  5,  6,  7],
#        [ 8,  9, 10, 11]])

a1.shape = (4, 3)
# array([[ 0,  1,  2],
#        [ 3,  4,  5],
#        [ 6,  7,  8],
#        [ 9, 10, 11]])

reshape:不改变原数组形状,返回一个临时数组

import numpy as np

a1 = np.arange(12)
# array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

a1.shape = [3, 4]
# array([[ 0,  1,  2,  3],
#        [ 4,  5,  6,  7],
#        [ 8,  9, 10, 11]])

a1.reshape(2, 2, 3)
# array([[[ 0,  1,  2],
#         [ 3,  4,  5]],
#
#        [[ 6,  7,  8],
#         [ 9, 10, 11]]])

a1
# array([[ 0,  1,  2,  3],
#        [ 4,  5,  6,  7],
#        [ 8,  9, 10, 11]])

# -1表示任意个元素,(2, -1)表示两行任意列
a1.reshape(2, -1)
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]]


np.reshape(a1, [3, 2, 2])
# array([[[ 0,  1],
#         [ 2,  3]],
#
#        [[ 4,  5],
#         [ 6,  7]],
#
#        [[ 8,  9],
#         [10, 11]]])

a1
# array([[ 0,  1,  2,  3],
#        [ 4,  5,  6,  7],
#        [ 8,  9, 10, 11]])

resize:将数组转换成指定的形状,会直接修改数组本身,并且不会返回任何值

import numpy as np

a1 = np.arange(12)
# array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

a1.shape = [3, 4]
# array([[ 0,  1,  2,  3],
#        [ 4,  5,  6,  7],
#        [ 8,  9, 10, 11]])

a1.resize(2, 2, 3)
a1
# array([[[ 0,  1,  2],
#         [ 3,  4,  5]],
#
#        [[ 6,  7,  8],
#         [ 9, 10, 11]]])

numpy.ndarray.flat 将数组转换为一维的迭代器,可以用for访问数组每一个元素。

import numpy as np

arr1 = np.arange(24).reshape(4, 6)
arr1
# 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]])

arr2 = arr1.flat
arr2 
# <numpy.flatiter at 0x1f6d67973f0>

for i in arr2:
    print(i, end=' ')
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

numpy.ndarray.flatten([order='C']) 将数组的副本转换为一维数组,并返回, flatten()函数返回
的是拷贝。

import numpy as np

arr1 = np.arange(24).reshape(4, 6)
arr1
# 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]])

arr2 = arr1.flatten()
arr2
# 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])

arr2[2] = 0
arr1
# 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]])

2. ndarray转置

numpy.transpose()、numpy.ndarray.T ,对换数组的维度,numpy.ndarray.T相当于numpy.transpose在二维矩阵情况下的一种简便表达。

import numpy as np

arr = np.random.randint(0, 10, size=(3, 4))
print(arr)
# [[8 7 7 7]
#  [7 1 9 1]
#  [4 1 4 1]]

print(arr.T)
# [[8 7 4]
#  [7 1 1]
#  [7 9 4]
#  [7 1 1]]

print(arr)
# [[8 7 7 7]
#  [7 1 9 1]
#  [4 1 4 1]]

print(np.transpose(arr))
# [[2 9 1]
#  [7 0 0]
#  [0 2 7]
#  [2 6 6]]

print(arr)
# [[8 7 7 7]
#  [7 1 9 1]
#  [4 1 4 1]]

3. ndarray组合

在数据分析中,数组组合应该是最常见的操作。数组组合的方式大致可分为两种:一种是沿现有轴(维度)组合数组;另一种是沿新轴(新的维度)组合数组。

  • numpy.concatenate((a1, a2, ...), axis=0, out=None) :沿现有轴连接一系列数组。
  • numpy.stack(arrays, axis=0, out=None):沿新轴连接一系列数组。
  • numpy.vstack(tup):水平(按列)顺序堆叠数组
  • numpy.hstack(tup):垂直(行)按顺序堆叠数组
import numpy as np

a1 = np.arange(12).reshape(3, 4)
a2 = np.arange(12, 24).reshape(3, 4)

# numpy.concatenate([a1, a2, ...], axis=0, out=None) 沿现有轴连接一系列数组
a3 = np.concatenate([a1, a2])
print(a3)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]
#  [12 13 14 15]
#  [16 17 18 19]
#  [20 21 22 23]]

a4 = np.concatenate([a1, a2], axis=1)       # axis默认为0
print(a4)
# [[ 0  1  2  3 12 13 14 15]
#  [ 4  5  6  7 16 17 18 19]
#  [ 8  9 10 11 20 21 22 23]]

# numpy.stack(arrays, axis=0, out=None) 沿新轴连接一系列数组,stack为增加维度的拼接
a5 = np.stack([a1, a2])
print(a5)
# [[[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]
#
#  [[12 13 14 15]
#   [16 17 18 19]
#   [20 21 22 23]]]

a6 = np.stack([a1, a2], axis=1)
print(a6)
# [[[ 0  1  2  3]
#   [12 13 14 15]]
#
#  [[ 4  5  6  7]
#   [16 17 18 19]]
#
#  [[ 8  9 10 11]
#   [20 21 22 23]]]

a7 = np.stack([a1, a2], axis=2)
print(a7)
# [[[ 0 12]
#   [ 1 13]
#   [ 2 14]
#   [ 3 15]]
#
#  [[ 4 16]
#   [ 5 17]
#   [ 6 18]
#   [ 7 19]]
#
#  [[ 8 20]
#   [ 9 21]
#   [10 22]
#   [11 23]]]

# hstack(), vstack() 分别表示水平和竖直的拼接方式。在数据维度等于1时,比较特殊。
# 而当维度大于或等于2时,它们的作用相当于 concatenate ,用于在已有轴上进行操作。
a8 = np.hstack([a1, a2])
print(a8)
# [[ 0  1  2  3 12 13 14 15]
#  [ 4  5  6  7 16 17 18 19]
#  [ 8  9 10 11 20 21 22 23]]

a9 = np.vstack([a1, a2])
print(a9)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]
#  [12 13 14 15]
#  [16 17 18 19]
#  [20 21 22 23]]

a0 = np.arange(5)
# [0 1 2 3 4]

a10 = np.hstack([a0, a0])
print(a10)
# [0 1 2 3 4 0 1 2 3 4]

a11 = np.vstack([a0, a0])
print(a11)
# [[0 1 2 3 4]
#  [0 1 2 3 4]]

4. ndarray拆分

numpy.split(ary, indices_or_sections, axis) 沿特定的轴将数组分割为子数组

  • ary:要切分的数组。
  • indices_or_sections:如果是一个整数,就用该数平均切分,如果是一个数组,为沿轴切分的位置(左开右闭)。
  • axis:沿着哪个维度进行切分,默认为0,横向切分。为1时,纵向切分。
import numpy as np

a1 = np.arange(9)

# 一维数组
a2 = np.split(a1, 3)        # 平均切分,注意整除
print(a2)
# [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]

a3 = np.split(a1, [3, 8])
print(a3)
# [array([0, 1, 2]), array([3, 4, 5, 6, 7]), array([8])]

# 二维数组
a1 = np.arange(12).reshape(3, 4)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]

a2 = np.split(a1, 3)
print(a2)
# [array([[0, 1, 2, 3]]),
#  array([[4, 5, 6, 7]]),
#  array([[8, 9, 10, 11]])]

a3 = np.split(a1, [1, 3])
print(a3)
# [array([[0, 1, 2, 3]]),
#  array([[4, 5, 6, 7],
#         [8, 9, 10, 11]]),
#  array([], shape=(0, 4), dtype=int32)]

a4 = np.split(a1, [1, 3], axis=1)
print(a4)
# [array([[0], [4], [8]]),
#  array([[1, 2], [5, 6], [9, 10]]),
#  array([[3], [7], [11]])]

5. ndarray排序

numpy.sort() 指定轴进行排序。默认是使用数组的最后一个轴进行排序。
ndarray.sort() 这个方法会直接影响到原来的数组,而不是返回一个新的排序后的数组。

import numpy as np

a1 = np.random.randint(0, 12, size=(3, 4))
print(a1)
# [[ 3  8  1  7]
#  [ 0  4 10  3]
#  [10  5  8 11]]

# numpy.sort 指定轴排序,不改变原数组
print(np.sort(a1))          # 默认axis=1, 行排序
# [[ 1  3  7  8]
#  [ 0  3  4 10]
#  [ 5  8 10 11]]

print(np.sort(a1, axis=0))  # 指定axis=0, 列排序
# [[ 0  4  1  3]
#  [ 3  5  8  7]
#  [10  8 10 11]]

print(-np.sort(-a1))         # 降序排序
# [[ 8  7  3  1]
#  [10  4  3  0]
#  [11 10  8  5]]

# ndarray.sort 直接修改原数组
a1.sort()
print(a1)
# [[ 1  3  7  8]
#  [ 0  3  4 10]
#  [ 5  8 10 11]]

a1.sort(axis=0)
print(a1)
# [[ 0  3  4  8]
#  [ 1  3  7 10]
#  [ 5  8 10 11]]

# numpy.argsort 返回排序后的下标值

二、NumPy数组运算

1. 基本运算

  • Numpy数组不需要写循环即可对数据执行批量运算
  • NumPy用户称其为矢量化(vectorization)

大小相等的数组之间的任何算术运算都会将运算应用到元素级:

import numpy as np

arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[2, 4, 6], [1, 3, 5]])

print(arr1 + arr2)
# [[ 3  6  9]
#  [ 5  8 11]]

print(arr1 - arr2)
# [[-1 -2 -3]
#  [ 3  2  1]]

print(arr1 * arr2)
# [[ 2  8 18]
#  [ 4 15 30]]

print(arr1 / arr2)
# [[0.5      0.5        0.5]
#  [4.       1.66667    1.2]]

print(arr1 ** 2)
# [[ 1  4  9]
#  [16 25 36]]

2. 逻辑函数

  • numpy.all() 函数用于判断整个数组中的元素的值是否全部满足条件,如果满足条件返回True,否则返回False。
  • numpy.any() 相当于或(or)操作,任意一个元素为True,输出为True
  • numpy.isnan() 函数用于判断数据是否为 NaN
  • numpy.isinf() 函数用于判断数据是否为 inf
import numpy as np

arr1 = np.arange(5)
arr2 = np.copy(arr1)
# [0 1 2 3 4]

print(np.all(arr1 == 0))        # False
print(np.all(arr1 == arr2))     # True

arr1[1] = 0
print(arr1 == arr2)             # [True False True True True]
print(np.all(arr1 == arr2))     # False
print(np.any(arr1 == arr2))     # True
print(np.any(arr1 == 0))        # True
print(np.any(arr1 == 10))       # False

3. 数学函数

函数名含义示例结果
numpy.addnp.add(np.array([1, 2, 3,4]), 1)array([2, 3, 4, 5])
numpy.subtractnp.subtract(np.array([1, 2, 3, 4]), 1)array([0, 1, 2, 3])
numpy.multiplynp.multiply(np.array([1, 2, 3, 4]), 2)array([2, 4, 6, 8])
numpy.dividenp.divide(np.array([1, 2, 3, 4]), 2)array([0.5, 1. , 1.5, 2.])
numpy.power

power(x, y)

计算 x 的 y 次方

np.power(2, 3)8
numpy.sqrt计算各元素的平
方根
np.sqrt([1, 4, 9])array([1., 2., 3.])
numpy.square计算各元素的平
np.square([1, 2, 3])array([1, 4, 9])
numpy.sum各元素求和np.sum(np.array([1, 2, 3]))6
numpy.cumsum各元素累加和np.cumsum(np.array([1, 2, 3]))array([1, 3, 6])
numpy.prod各元素的乘积np.prod(np.array([1, 2, 3, 4]))24
numpy.cumprod各元素累积乘积np.prod(np.array([1, 2, 3, 4]))array([ 1, 2, 6, 24])
numpy.min最小的元素np.min(np.array([1, 2, 3, 4]))1
numpy.max最大的元素np.max(np.array([1, 2, 3, 4]))4
numpy.mean元素的均值np.mean(np.array([1, 2, 3, 4]))2.5
numpy.around

四舍五入

可指定精度

np.around(np.array([1.2, 2.6, 3.1, 4.7]))array([1., 3., 3., 5.])
numpy.ceil向上取整np.ceil(np.array([-2.1, -1.7,1.2, 2.6, 3.1]))array([-2., -1., 2., 3., 4.])
numpy.floor向下取整np.floor(np.array([-2.1, -1.7, 1.2, 2.6, 3.1]))array([-3., -2., 1., 2., 3.])
numpy.exp返回e的幂次方np.exp(np.array([1, 2]))array([2.718, 7.389])
numpy.log

自然对数

以e为底

np.log(np.e)1.0

三、日期时间的表示和间隔

在 Numpy中,我们可以很方便的将字符串转换成时间日期类型datetime64(datetime已被Python 包含的日期时间库所占用)。

日期单位代码含义时间单位代码含义
Yh小时
Mm分钟
Ws
Dms毫秒

1. 日期时间的表示——datetime64

字符串转时间类型时,NumPy会根据字符串自动选择对应的单位,也可以强制指定使用单位。

import numpy as np

dt1 = np.datetime64('2023-06-01')
print(dt1, dt1.dtype)   # 2023-06-01 datetime64[D]

dt2 = np.datetime64('2023-06')
print(dt2, dt2.dtype)   # 2023-06 datetime64[M]

dt3 = np.datetime64('2023-06-01 10')
print(dt3, dt3.dtype)   # 2023-06-01T10 datetime64[h]

dt4 = np.datetime64('2023-06-01 10:30:59')
print(dt4, dt4.dtype)   # 2023-06-01T10:30:59 datetime64[s]

dt5 = np.datetime64('2023', 'D')
print(dt5, dt5.dtype)   # 2023-01-01 datetime64[D]

dt6 = np.datetime64('2023-01-01 23:00:00', 'h')
print(dt6, dt6.dtype)   # 2023-01-01T23 datetime64[h]

dt_lst = np.array(['2023-06', '2022-10-20', '2021', '2023-03-10 17:50:20'], dtype='datetime64')
print(dt_lst, dt_lst.dtype)
# ['2023-06-01T00:00:00' '2022-10-20T00:00:00' '2021-01-01T00:00:00' '2023-03-10T17:50:20'] datetime64[s]

2. 日期时间的计算——timedelta64

timedelta64 表示两个 datetime64 之间的差。

相减后timedelta64的单位与两个 datetime64 中的较小的单位保持一致。

import numpy as np

dt1 = np.datetime64('2023-01-01')

dt2 = dt1 - np.datetime64('2022-01-01')
dt3 = dt1 - np.datetime64('2022-12-01 12')
dt4 = dt1 - np.datetime64('2021-06')

print(f"{dt2}, {dt3}, {dt4}")
# 365 days, 732 hours, 579 days

# 不支持 M 和 Y 的运算
dt5 = dt1 + np.timedelta64(10, 'D')
dt6 = dt1 + np.timedelta64(10, 'h')
dt7 = dt1 - np.timedelta64(10, 'm')
dt8 = dt1 - np.timedelta64(10, 's')
print(f"{dt5}, {dt6}, {dt7}, {dt8}")
# 2023-01-11, 2023-01-01T10, 2022-12-31T23:50, 2022-12-31T23:59:50

3. datetime64与datetime的转换

import numpy as np
import datetime

dt1 = datetime.datetime(year=2022, month=10, day=1, hour=10, minute=30, second=30)
dt64 = np.datetime64(dt1, 's')
print(dt64, dt64.dtype)
# 2022-10-01T10:30:30 datetime64[s]

dt2 = dt64.astype(datetime.datetime)
print(dt2, type(dt2))
# 2022-10-01 10:30:30 <class 'datetime.datetime'>

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AllinTome

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值