NumPy 面试问题:为 Python 工作面试做好准备

NumPy 是 Python 中的开源科学数值库。它从根本上用于执行涉及矩阵和数组的数学计算。它包含许多本质上是高级的数学函数,这些函数对数组进行操作以提供输出。

NumPy 最初是由 Jim Hugunin 和其他几位作为该项目贡献者的开发人员开发的Numeric 。2005 年,Travis Oliphant 合并了 Numarray,这是一个与 Numeric 竞争的类似库。他将 Numarray 的特性融入到 Numeric 中,从而创建了 NumPy。

另请阅读:Pandas Dataframe 和 Numpy 数组之间的区别

主要特征

以下是 NumPy 最重要的功能,这些功能使其在整个技术社区中非常受欢迎。

  1. N 维数组– NumPy 非常快速、强大且用途广泛。它使用矢量化技术来执行数学运算。还合并了广播和索引作为数组计算的标准概念。
  2. 提供基于数字的计算工具– NumPy 可以处理许多数学和复杂的函数。其中包括线性代数、随机数生成器、傅里叶变换等,它们在科学计算中广泛使用。
  3. 能够使用多个连接的设备和硬件——具体称为互操作性,NumPy 支持多种类型的硬件、计算平台、图形处理单元、分布式计算功能和稀疏数组库集成,使其成为最强大的 Python 库之一周围有一个大社区。
  4. 优化且高性能的代码执行– NumPy 在其核心中融入了高性能的 C 代码编译,提供高效、高速的代码执行。
  5. 用户友好——NumPy 提供了非常易读且简单的 Python 语法,这使得它用户友好。使用它的代码要求很少并且易于调试。因此,使其可供各级编码员和跨多个行业使用和编程。
  6. 开源——NumPy 拥有一个庞大且多元化的社区,拥有众多开源贡献者。它带有 BSD 许可证,在 GitHub 上公开开发和维护。

NumPy 在现实世界数据分析中的示例

NumPy 被科学界广泛使用,这使得它在各个重要层面都脱颖而出。以下是一些示例,可让您一睹其风采。完整的案例研究可以在 NumPy 官方网站上阅读

  1. 第一张黑洞图像– NumPy 以及使用 NumPy 作为依赖项的其他科学库(例如 Matplotlib 和 SciPy),利用事件视界望远镜生成了第一张黑洞图像。
  2. 引力波的检测– 自阿尔伯特·爱因斯坦于 1916 年首次预测引力波以来,100 年后,LIGO 科学家使用 NumPy 证实了引力波的存在。
  3. 体育分析——体育行业大量使用预测分析和数据建模来提供球队和球员的统计分析,以提高他们的表现。在大多数情况下,NumPy 正是用于此目的。
  4. 使用深度学习进行姿势估计– 使用 DeepLabCuts 的 NumPy 进行动物行为观察,以更好地了解运动控制、物种和时间尺度,以进行快节奏的科学研究。

理论 NumPy 面试问题

1.什么是NumPy,它的基本特性是什么?

NumPy 是 Python 中的科学计算包/库。它提供了一个多维的数组对象以及多个派生对象,例如屏蔽数组和矩阵。NumPy 包的核心是ndarray 。它负责封装同质数据类型的 n 维数组,提供优化的代码编译,使其性能非常好。它从根本上用于执行数学和逻辑运算、实现基本线性代数、操作数组形状、排序和选择、I/O、执行离散傅立叶变换等。

2. NumPy 是用什么语言编写的?

NumPy 本质上是一个 Python 库。它主要用C/C++编写,目的是快速和优化代码执行。然而,NumPy 的某些部分也是使用 Python 编写的。

3. 使用 NumPy 的主要原因是什么?

NumPy 是一个跨行业非常流行的 Python 库。数据科学是利用该库的主要领域之一。大多数科学计算都使用数组。在执行高级和复杂的计算时,为了尽快获得结果,高效和快速的代码执行是不可避免的。

虽然 Python 列表也是数组,但这些列表的处理时间比 NumPy 数组慢 50 倍,使其成为执行数值和科学计算的最流行的库。在 NumPy 中,数组对象称为ndarray,它提供了许多附加功能,使其更快、更易于使用。

4. 标准 Python 序列和 NumPy 数组之间有哪些重要区别?

以下是两者之间的一些最显着的差异。

  • Python 列表可以动态增长,而 NumPy 数组在创建时的大小是固定的。因此,当我们更改ndarray的大小时,它会删除原始数组并创建一个新数组。
  • 在计算高级数学和包含大量数据的各种其他类型的运算时,NumPy 的性能要高得多。使用 Python 进行计算需要更多代码,而且效率不如 NumPy。
  • NumPy 数组的所有元素的数据类型都相同,因此与 Python 数组不同,它占用固定的内存大小。然而,有一个例外,即可以拥有对象数组(Python 以及 Numpy),允许数组使用不同大小的元素。
  • 许多科学界使用基于 Python 的软件包进行高级计算,其中都包含 NumPy 数组。基于 Python 的序列通常会在预处理数据时转换为 NumPy 数组,并将结果输出为 NumPy 数组。因此,编写高效的基于 Python 的科学计算需要 NumPy 数组的知识。

5. 是什么让 NumPy 数组比 Python 列表更快?

创建和保存列表时,它们存储在随机内存位置,如果对其进行操作,则需要更长的时间来访问和处理。这就是 NumPy 数组的闪光点。它们作为 ndarray 存储在一个连续的内存位置,使得操作和计算非常高效和优化。这种类型的代码执行与现代 CPU 架构一致,因此,使 NumPy 成为一个非常快速且优化的 Python 库。

6. 简要解释 NumPy 中的数组。

在NumPy库中,数组是核心数据结构。数组包含原始数据信息并提供解释项目和定位元素的方法。数组中的元素可以通过多种方式进行索引,并包含元素网格。

数组中的元素类型称为dtype,它们也必须具有相同的数据类型。维数与数组的秩有关。整数元组是数组的形状,提供沿每个维度的数组大小。

7.列出NumPy ndarray对象的一些重要属性

以下是ndarray对象的一些主要属性

  • ndarray.shape – 它输出数组维度。对于包含n 行m 列的矩阵,形状将为(n, m)要获取给定 array 的轴数请使用 ndarray.ndim 。
  • ndarray.dtype – 它描述数组中包含的元素的数据类型。我们还可以使用标准 Python 指定数据类型。NumPy 还提供了自己的附加数据类型。其中一些示例是numpy.int16、numpy.int32numpy.float64
  • ndarray.itemsize – 它输出给定数组的每个元素的大小(以字节为单位)。它与使用ndarray.dtype.itemsize相同举例来说,我们有一个包含float64类型元素的数组。它的项目大小将为8 ,这是64/8的结果另一种情况是当包含的数据类型是complex32时。它的项目大小将为4,即32/8
  • ndarray.data – 它返回保存数组的内存位置或缓冲区。它不经常使用,因为我们使用索引作为对该内存位置的引用来获取数组中包含的元素。

8. NumPy 中的通用函数是什么?

exp、sin、cos、add、sqrt等数学函数在 Numpy 中称为通用函数ufunc 。它们在 NumPy 中按元素操作数组,并以数组形式提供输出。他们使用矢量化来实现操作,并且还支持广播以及其他方法,例如accumulatereduce

9. 解释 NumPy 中的术语“广播”。

每当我们有不同维度的数组时,NumPy 都会以统一的方式处理它们,同时执行算术、函数、按位以及逻辑运算。这称为广播它用于解释逐个元素隐式完成的操作行为。

NumPy 广播

10. 如何将一维数组转换为二维数组?

要增加给定数组的维度,我们可以使用NumPy 提供的np.newaxisnp.expand_dims函数。因此,我们可以将 1D 转换为 2D、2D 转换为 3D 等等。

11. 解释NumPy 中复制视图之间的主要区别。

当我们在 NumPy 中使用copy() 函数时,它会创建一个全新的数组。我们在原始数组中所做的更改不会反映在其复制版本中。另一方面,view()函数只是原始数组的反射。无论我们在原始数组中进行什么更改,也都将在使用视图函数调用的数组中实现。

12. NumPy 和 Pandas 有什么不同?

以下是 NumPy 和 Pandas 之间的一些区别。

  • NumPy 比 Pandas 更快且内存效率更高。
  • NumPy 主要用于数值计算,而 Pandas 用于更广泛的用途,例如数据分析和可视化。
  • NumPy 支持使用矩阵和数组数据格式,其中 Pandas 可以与表数据、Excel 文件、CSV 文件等一起使用。
  • NumPy 使用数组作为其主要对象,并且默认情况下也不索引。Pandas 使用系列和数据框作为其主要对象,并默认提供索引。

13. 说明 NumPy 和 SciPy 之间的差异。

NumPy 实现了索引、排序等基本功能,这使得它轻量且紧凑。另一方面,SciPy 用于涉及算法和代数函数的复杂计算。这使得它具有更多的功能。

与 SciPy 不同,NumPy 中的函数定义不是非常全面。NumPy 的限制之一是所操作的数组必须是相同类型或同类的。SciPy 没有这种同质性的限制,使其更加灵活和通用。

Numpy 部分使用 Python 编写,大部分使用 C 语言进行代码编译和执行。SciPy 是使用 Python 编写的,与 NumPy 相比,它的速度较慢,但​​它也提供了比 NumPy 更多的功能。

14. NumPy 为数组迭代提供了哪些函数?

nditer()NumPy 提供的函数ndenumerate()可用于对不同维度的数组执行迭代操作。

15. NumPy 中如何连接数组?

我们可以使用concatenate()stack()函数来连接 NumPy 数组。这两个函数都输出相似的结果,不同之处在于堆叠操作是沿着新轴执行的,这与串联不同。

NumPy 编码问题

1.如何安装NumPy?

  • 与康达
# Using an environment
conda create -n my-env
conda activate my-env
 
# Install using conda-forge
conda config --env --add channels conda-forge
 
# Installation command
conda install numpy
  • 带有画中画
pip install numpy

另请阅读:Conda 与 Pip:选择你的 Python 包管理器

2. 导入 NumPy 并使用它创建一个简单的数组。

import numpy as np
 
array1 = np.array([10, 12, 14, 16])
print(array1)

3. 如何查看已安装的NumPy版本?

import numpy as np
 
np.__version__
 
# Output: '1.21.5'

4. 如何使用 NumPy 创建不同维度的数组?另外,检查尺寸。

import numpy as np
 
first_array = np.array(10) # 0D Array
second_array = np.array([21, 22, 23, 24, 25]) # 1D Array
third_array = np.array([[21, 22, 23], [24, 25, 26]]) # 2D Array
fourth_array = np.array([[[10, 20, 30], [40, 50, 60]], [[10, 20, 30], [40, 50, 60]]]) # 3D Array
 
first_array, first_array.ndim
 
# Output: (array(10), 0)
 
second_array, second_array.ndim
 
# Output: (array([21, 22, 23, 24, 25]), 1)
 
third_array, third_array.ndim
 
# Output:
 
"""
(array([[21, 22, 23],
        [24, 25, 26]]),
 2)
 
"""
 
fourth_array, fourth_array.ndim
 
# Output:
 
"""
(array([[[10, 20, 30],
         [40, 50, 60]],
  
        [[10, 20, 30],
         [40, 50, 60]]]),
 3)
 
"""

5. 如何使用 NumPy 创建更高维度的数组?

import numpy as np
 
higher_dimension_array = np.array([10, 20, 30, 40], ndmin=7)
 
higher_dimension_array
 
# Output: array([[[[[[[10, 20, 30, 40]]]]]]])
 
'Dimensions :', higher_dimension_array.ndim
 
# Output: ('Dimensions :', 7)

6. 提供 NumPy ndarray属性的使用示例

  • ndarray.shape
import numpy as np
 
my_array = np.arange(10).reshape(2, 5)
my_array
 
# Output
 
"""
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])
 
"""
 
my_array.shape
 
# Output
 
"""
(2, 5)
"""
  • ndarray.dtype
my_array.dtype
 
# Output
 
"""
dtype('int32')
"""
  • ndarray.itemsize
r_part = [2, 3, 4]
i_part = [6, 7, 8]
 
my_complex_array = np.array([r_part, i_part], dtype=complex)
 
my_complex_array
 
# Output
 
"""
 
array([[2.+0.j, 3.+0.j, 4.+0.j],
       [6.+0.j, 7.+0.j, 8.+0.j]])
 
"""
my_complex_array.dtype
 
# Output
 
"""
dtype('complex128')
"""
 
my_complex_array.itemsize
 
# Output
 
"""
16
"""
  • ndarray.数据
my_array.data
 
# Output
 
"""
<memory at 0x000001E8ABFEDBA0>
"""

7. 如何使用 NumPy 创建不同数据类型的数组?

我们可以通过多种方式使用 NumPy 创建数组。数组类型推导是根据这些序列中包含的元素类型完成的。以下是一些示例。

  • int 数据类型
first_array = np.array([1, 2, 3])
first_array
 
# Output: array([1, 2, 3])
 
first_array.dtype
# Output: dtype('int32')
  • 浮点数据类型
second_array = np.array([2.3, 4.5, 6.7])
second_array
 
# Output: array([2.3, 4.5, 6.7])
 
second_array.dtype
# Output: dtype('float64')
  • 多种数据类型
third_array = np.array([(2.3, 8.7, 3.2), (1, 2, 3)])
third_array
 
# Output
 
"""
array([[2.3, 8.7, 3.2],
       [1. , 2. , 3. ]])
 
"""

8. 如何使用 NumPy 创建复杂类型数组?

import numpy as np
 
complex_type_array = np.array([[1, 2, 4], [9, 10, 5]], dtype=complex)
 
complex_type_array
 
# Output
 
"""
array([[ 1.+0.j,  2.+0.j,  4.+0.j],
       [ 9.+0.j, 10.+0.j,  5.+0.j]])
 
"""

9. 如何使用内置函数创建 NumPy 数组?

  • 使用“arange”函数创建数组
import numpy as np
 
np.arange(1, 20, 3)
 
# Output: array([ 1,  4,  7, 10, 13, 16, 19])
  • 创建具有等效线性间距的阵列
import numpy as np
 
np.linspace(0, 1, 4 )
 
# Output : array([0.        , 0.33333333, 0.66666667, 1.        ])
  • 创建固定形状的零数组
import numpy as np
 
np.zeros((4, 5))
 
# Output:
 
"""
array([[0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.]])
 
"""
  • 创建固定形状的数组
import numpy as np
 
np.ones((4, 5))
 
# Output
 
"""
array([[1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.]])
 
"""

10. 给出使用 NumPy 中通用函数的示例。

import numpy as np
 
first_array = np.arange(1, 5)
second_array = np.arange(6, 10)
 
first_array, second_array
 
# Output: (array([1, 2, 3, 4]), array([6, 7, 8, 9]))
 
np.sqrt(first_array)
 
# Output: array([1.        , 1.41421356, 1.73205081, 2.        ])
 
np.add(first_array, second_array)
 
# Output: array([ 7,  9, 11, 13])

11. 使用 NumPy 中的函数创建二维数组np.newaxis

import numpy as np
 
#  Create 1D array
first_array = np.array([3, 4, 5, 6, 7])
 
first_array.shape
 
# Output: (5,)
 
# Adding a new axis to our 1D array: with np.newaxis
 
second_array = first_array[np.newaxis, :]
 
second_array.shape
 
# Output: (1, 5)
 
# Adding another axis to our 2D array: with np.newaxis
 
third_array = second_array[np.newaxis, :]
 
third_array.shape
 
# Output: (1, 1, 5)

12. 创建显示np.expand_dims函数用法的 NumPy 数组。

import numpy as np
 
# Creating a 1D array
 
first_array = np.arange(6)
 
first_array
 
# Output: array([0, 1, 2, 3, 4, 5])
 
first_array.shape
 
# Output: (6,)
 
# Adding a new axis to our 1D array at position 0: with np.expand_dims
 
second_array = np.expand_dims(first_array, axis=0)
second_array
 
# Output: array([[0, 1, 2, 3, 4, 5]])
 
second_array.shape
 
# Output: (1, 6)
 
# Adding a new axis to our 1D array at position 1: with np.expand_dims
 
third_array = np.expand_dims(first_array, axis=1)
third_array.shape
 
# Output: (6, 1)

13. 展示一些使用 1D、2D 和 3D 数组访问数组值的示例。

  • 访问一维数组中的元素
import numpy as np
 
first_array = np.array([25, 30, 35, 40])
 
first_array[1] # Output: 30
  • 访问二维数组中的元素
import numpy as np
 
my_array = np.array([[22, 33, 44, 55], [66, 77, 88, 99]])
 
# Accessing row 2, element 3
my_array[1, 2] # Output: 88
  • 访问 3D 数组中的元素
import numpy as np
 
my_array = np.array([[[11, 22, 33], [44, 55, 66]], [[77, 88, 99], [100, 111, 122]]])
 
# Accessing 3rd element of 2nd array of 1st array
my_array[0, 1, 2] # Output: 66

14. 显示使用 NumPy 2D 数组进行负索引的示例。

import numpy as np
 
my_array = np.array([[77, 88, 99], [100, 111, 122]])
 
# Accessing the last element from the first dimension
my_array[0, -1] # Output: 99

15.我们如何知道数组的形状?另外,首先将 1D 数组重塑为 2D,然后将 1D 数组重塑为 3D 数组

import numpy as np
 
my_array = np.arange(16)
 
my_array
 
# Output: array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])
 
# 1D Array
my_array.shape # Output: (16,)
  • 将一维数组转换为二维数组
my_array.reshape(4, 4)
 
"""
Output:
 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
 
"""
  • 将 1D 数组转换为 3D 数组
# Convert 1D to 3D Array
my_array.reshape(4, 2, 2)
 
"""
Output:
 
array([[[ 0,  1],
        [ 2,  3]],
 
       [[ 4,  5],
        [ 6,  7]],
 
       [[ 8,  9],
        [10, 11]],
 
       [[12, 13],
        [14, 15]]])
 
"""

16.展示NumPy中复制函数的用法

import numpy as np
 
my_array = np.array([14, 15, 16, 17, 18])
my_array_copy = my_array.copy()
my_array[-1] = 100
 
print(my_array)
print(my_array_copy)
 
"""
Output:
 
[ 14  15  16  17 100]
[14 15 16 17 18]
 
"""

17.展示NumPy中视图函数的用法

view 函数创建一个类似别名的 Numpy 数组,将所有更改复制到新数组。

import numpy as np
 
my_array = np.array([14, 15, 16, 17, 18])
my_array_view = my_array.view()
my_array[-1] = 100
 
print(my_array)
print(my_array_view)
 
"""
Output:
[ 14  15  16  17 100]
[ 14  15  16  17 100]
 
"""

18. NumPy 中如何使用arange函数?

import numpy as np
 
my_array = np.arange(5)
 
my_array
 
# Output: array([0, 1, 2, 3, 4])
  • 排列:带有“开始”和“停止
my_array = np.arange(1, 10)
 
my_array
 
# Output: array([1, 2, 3, 4, 5, 6, 7, 8, 9])
  • arange:带有“开始”和“停止”和“步长
my_array = np.arange(1, 14, 3)
 
my_array
 
# Output: array([ 1,  4,  7, 10, 13])
  • arange:带有“ start ”、“ stop ”和“ stepsize ”的 计数
my_array = np.arange(25, 0, -4)
 
my_array
 
# Output: array([25, 21, 17, 13,  9,  5,  1])

19. 给出在 NumPy 中迭代一维和二维数组的示例。

  • 一维数组迭代
import numpy as np
 
my_array = np.arange(5)
 
for eachItem in my_array:
  print(eachItem)
 
"""
Output:
 
0
1
2
3
4
 
"""
  • 二维数组迭代
import numpy as np
 
my_array = np.array([[14, 15, 16], [17, 18, 19]])
 
for eachItem in my_array:
  print(eachItem)
 
"""
Output:
 
[14 15 16]
[17 18 19]
 
"""
  • 迭代二维数组中的每个标量项
import numpy as np
 
my_array = np.array([[14, 15], [17, 19]])
 
for each in my_array:
  for eachItem in each:
    print(eachItem)
"""
Output:
 
14
15
17
19
 
""" 

20. 如何使用 nditer() 函数进行迭代?

import numpy as np
 
my_array = np.array([[12, 13], [14, 15]])
 
for each_scalar_item in np.nditer(my_array):
  print(each_scalar_item)
 
"""
 
Output:
 
12
13
14
15
 
"""

21. 显示提供步长的 nditer() 函数的用法。

import numpy as np
 
my_array = np.array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]])
 
for eachItem in np.nditer(my_array[:, ::3]):
  print(eachItem)
 
"""
Output:
 
0
3
5
8
 
"""

22. 给出一个使用 ndenumerate() 函数的例子。

import numpy as np
 
my_array = np.array([[12, 13], [14, 15]])
 
for index, eachItem in np.ndenumerate(my_array):
  print(index, eachItem)
 
"""
Output:
 
(0, 0) 12
(0, 1) 13
(1, 0) 14
(1, 1) 15
 
"""

23. 如何使用 NumPy 中的 concatenate 函数连接两个数组?

import numpy as np
 
first_array = np.array([1, 2, 3])
 
second_array = np.array([4, 5, 6])
 
concatenated_array = np.concatenate((first_array, second_array))
 
concatenated_array
 
# Output: array([1, 2, 3, 4, 5, 6])

24. 使用 stack 函数连接两个 NumPy 数组。

import numpy as np
 
first_array = np.array([1, 2, 3])
 
second_array = np.array([4, 5, 6])
 
stacked_array = np.stack((first_array, second_array))
 
stacked_array
 
"""
Output:
 
array([[1, 2, 3],
       [4, 5, 6]])
 
"""

25. NumPy 中如何使用 where() 函数?

  • 搜索数组中包含值 10 的所有索引
import numpy as np
 
my_array = np.array([10, 20, 30, 10, 40, 50, 60, 10])
 
search_indexes_for_ten = np.where(my_array == 10)
 
search_indexes_for_ten
 
# Output: (array([0, 3, 7], dtype=int64),)
  • 搜索所有值为偶数的索引
import numpy as np
 
my_array = np.array([10, 11, 12, 15, 21, 26])
 
search_indexes_for_even = np.where(my_array % 2 == 0)
 
search_indexes_for_even
 
# Output: (array([0, 2, 5], dtype=int64),)

概括

这些是 NumPy 库中的一些重要概念和问题。我希望这篇文章有助于更好地概述 NumPy 提供的功能和方法。

参考

NumPy 官方文档