Courses
NumPy 是数据科学家工具包中的基础组件。它使 Python 在处理大规模数据时也能进行高效的数据运算。
NumPy 提供的工具集(如便捷的逐元素计算、矩阵乘法和向量化)让它成为在 Python 中执行复杂计算的首选。因此,它在面试过程中经常出现。请通过阅读本文温习一些可能被问到的问题!
此外,您也可以在 DataCamp 上查看其他资源,进行更多 NumPy 的动手练习。
基础 NumPy 面试题
使用这些基础面试题来检查您对 NumPy 基础的理解。它们是很好的热身与起点,帮助您确认自己掌握了 NumPy 的功能与用途。
1. 什么是 NumPy,为何在数据科学中使用它?
NumPy 是一个 Python 包,其中许多部分用 C/C++ 编写以提升性能。其主要目标是在 Python 中更快速、更易于地计算大型数据数组。其核心功能如下:
- 为大型的多维数组与矩阵提供支持,这对于处理大规模数据集至关重要。
- 提供全面的数学函数集合,可高效地对这些数组进行操作,从而在大数据集上实现快速计算。
- NumPy 的向量化操作能高效执行复杂的数学运算。
- 它是许多其他数据科学库(如 pandas、scikit-learn 和 SciPy)的基础,是 Python 数据科学生态的基石。
- 与 Python 列表相比,NumPy 数组更节省内存,这在处理大数据时尤为关键。
2. 如何在 NumPy 中创建一维数组?
创建 Numpy 数组非常简单!只需调用 array() 方法即可创建数组对象。理解如何创建一维数组,将帮助您进一步构建更高维度的 NumPy 数组。
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
3. Python 列表与 NumPy 数组有什么区别?
Python 列表与NumPy 数组的主要区别有:
- 同质性:NumPy 数组是同质的,即所有元素必须是相同类型。Python 列表可以包含不同类型的元素。
- 内存效率:NumPy 数组以连续内存块存储数据,更加节省内存;而 Python 列表存储的是对象的指针。
- 性能:NumPy 数组支持向量化操作,在数值计算上要快得多。操作以逐元素方式执行,无需显式循环。
- 功能性:NumPy 数组自带大量可直接作用于数组的数学运算与函数,而这在 Python 列表上并不可行。
4. 如何查看 NumPy 数组的形状与大小?
理解如何查看 NumPy 数组的形状很重要,因为在数据处理过程中,您可能有一个期望的最终输出数组大小。
如果结果不符合预期,检查 NumPy 数组的形状有助于定位并解决问题。您可以使用 shape 属性获取数组维度,使用 size 属性获取元素总数:
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.shape) # Output: (2, 3)
print(arr.size) # Output: 6
5. 如何重塑(reshape)一个 NumPy 数组?
在数据预处理与特征工程中,重塑数组是常见操作。这对于适配不同算法的输入要求或为分析而重组数据非常关键。
您可以使用 reshape() 方法或 np.reshape() 函数来重塑 NumPy 数组。示例如下:
import numpy as np
# Using reshape() method
arr = np.array([1, 2, 3, 4, 5, 6])
reshaped_arr = arr.reshape(2, 3)
print(reshaped_arr)
# Output:
# [[1 2 3]
# [4 5 6]]
# Using np.reshape() function
arr = np.array([1, 2, 3, 4, 5, 6])
reshaped_arr = np.reshape(arr, (3, 2))
print(reshaped_arr)
# Output:
# [[1 2]
# [3 4]
# [5 6]]中级 NumPy 面试题
这些问题更深入地聚焦于 NumPy 的实际使用。当您已经建立起对 NumPy 数组的基础理解后,就该探索它的更多功能了。在中级层面,通常需要能用 NumPy 执行各种计算。
6. 如何创建全零或全一的数组?
在许多数据科学任务中,需要创建充满 0 或 1 的数组,例如初始化矩阵、创建掩码数组或搭建占位数据结构。
在 NumPy 中,可使用 np.zeros() 或 np.ones() 来创建全零或全一数组:
import numpy as np
# Create a 3x4 array of zeros
zeros_arr = np.zeros((3, 4))
print(zeros_arr)
# Output:
# [[0. 0. 0. 0.]
# [0. 0. 0. 0.]
# [0. 0. 0. 0.]]
# Create a 2x2 array of ones
ones_arr = np.ones((2, 2))
print(ones_arr)
# Output:
# [[1. 1.]
# [1. 1.]]
7. 什么是 NumPy 中的广播(broadcasting)?
广播是 NumPy 的关键机制,使得在不同大小的数组之间进行高效运算成为可能。
简而言之,它通过确保两个数组形状兼容,使得它们可以进行算术运算。NumPy 会自动在较大的数组上“复制”较小的数组,以匹配形状并完成运算。
请看以下示例:
import numpy as np
a = np.array([1, 2, 3])b = np.array([[1], [2], [3]])
print(a + b)
# Output:
# [[2 3 4]
# [3 4 5]
# [4 5 6]]
8. 如何求一个 NumPy 数组的均值、中位数与标准差?
均值、中位数与标准差是理解数据的关键描述性统计量。NumPy 提供了专门的函数,非常便于计算这些统计量。
掌握这些计算有助于更高效地利用 NumPy:
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
# Mean
mean_value = np.mean(arr)
print("Mean:", mean_value) # Output: 3.0
# Median
median_value = np.median(arr)
print("Median:", median_value) # Output: 3.0
# Standard deviation
std_value = np.std(arr)
print("Standard deviation:", std_value) # Output: 1.4142135623730951
9. 我们如何利用 NumPy 快速查询数值数据,并基于布尔条件执行操作?
虽然我们通常将 NumPy 视为计算包,但它也具备强大的数据整理能力。
NumPy 能通过布尔索引轻松查询数据,并基于结果执行操作。当我们希望根据数值修改数据时,where() 方法尤其有用。
假设我们有一个名为 df 的考试成绩数据框,并希望对学生进行分类。一个简单的 np.where() 如下:
df[‘student_cat’] = np.where(df[‘score’] > 80, ‘good’, ‘bad’)
请注意,where() 方法最多接收 3 个参数:
- 第一个是任意布尔条件
- 第二个是在条件为真时的结果
- 第三个是在条件为假时的结果
10. 如何利用 NumPy 计算诸如均方误差(MSE)之类的指标?
NumPy 能一次性作用于整个数组,这使得实现均方误差(MSE)等计算变得简单。
由于它以逐元素的方式执行简单运算,因此能轻松向量化该过程,高效地计算 MSE。
下面是一个在 NumPy 中实现 MSE 的示例:
# 1. We have two arrays, our prediction, and actual labels
# 2. We take the squared differences and sum them
# 3. We then divide by n, which is the length of the array
n= len(labels)
error = (1/n) * np.sum(np.square(predictions - labels))
高级 NumPy 面试题
现在,是时候进入更高级的领域了!在这个层面,期望您能使用 NumPy 解决更复杂的问题。
11. 如何使用 NumPy 计算滚动统计量,例如滚动均值?
滚动统计量(如滚动平均)在数据科学中非常重要。滚动均值常用于平滑噪声数据,尤其是时间序列。
NumPy 有一项鲜为人知的功能叫作“stride(步幅)”。其中一种实现方式是创建数组的滑动窗口视图。使用 lib.stride_tricks.sliding_window_view(),您可以轻松生成数组子集。
随后即可对每个子集进行任意汇总,例如计算均值,从而得到滚动平均。以下是示例实现:
import numpy as np
from numpy.lib.stride_tricks import sliding_window_view
x = np.arange(6)
v = sliding_window_view(x, 3)
# This creates v, an array that contains subarrays of length 3 which reflect the size of the window.
12. 如何进行高级索引,从多维数组中基于条件选择元素?
索引虽是 NumPy 的基础技能,但运用更高级的索引技巧能让数据科学家更精细地切片数据。
通过整型数组索引与布尔索引,创建满足特定条件的数据集将变得易如反掌。
import numpy as np
array = np.array([[10, 15, 20, 25],
[30, 35, 40, 45],
[50, 55, 60, 65]])
print(array) # Output:
# [[10 15 20 25]
# [30 35 40 45]
# [50 55 60 65]]
# Boolean indexing: Select elements greater than 30
condition = array > 30
print(condition) # Output:
# [[False False False False]
# [False True True True]
# [ True True True True]]
# Apply the condition to get the elements that meet the criteria
filtered_elements = array[condition]
print(filtered_elements) # Output: [35 40 45 50 55 60 65]
# Integer array indexing: Select specific elements based on row and column indices
row_indices = np.array([0, 1, 2])
col_indices = np.array([1, 2, 3])
selected_elements = array[row_indices, col_indices]
print(selected_elements) # Output: [15 40 65]
# Combining boolean and integer indexing
# Select elements from the array where the element is greater than 30 and belongs to specific indices
combined_condition = (array > 30) & ((row_indices[:, None] == np.arange(3)).any(axis=0))
filtered_selected_elements = array[combined_condition]
print(filtered_selected_elements) # Output: [35 40 45 50 55 60 65]
13. 如何使用 NumPy 执行线性代数运算,如矩阵分解或求解线性方程组?
对于处理海量数据的数据科学家来说,进行矩阵分解至关重要。将数据降至其主成分是降低复杂度与噪声的关键第一步。
NumPy 的 linalg 模块可以轻松执行线性代数运算以获取主成分。
# The underlying signal is a sinusoidally modulated image
img = lena() # This is from scipy.misc import lena
t = np.arange(100)
time = np.sin(0.1*t)
true= time[:,np.newaxis,np.newaxis] * img[np.newaxis,...]
# We add some noise
noisy = real + np.random.randn(*true.shape)*255
# (observations, features) matrix
M = noisy.reshape(noisy.shape[0],-1)
# Singular value decomposition factorizes your data matrix such that:
# M = U*S*V.T (where '*' is matrix multiplication)
# * U and V are the singular matrices containing orthogonal vectors of unit length
# * S is a diagonal matrix containing the singular values of M - we can use this to calculate our PCs
# Obtain the results of SVD from our noisy matrix
U, s, Vt = np.linalg.svd(M, full_matrices=False)
# Transpose V to get our PC vectors
V = Vt.T
# PCs are already sorted by descending order of the singular values (i.e. by the proportion of total variance they explain)
# If we use all of the PCs we can reconstruct the noisy signal perfectly
S = np.diag(s)
Mhat = np.dot(U, np.dot(S, V.T))
print(“Using all PCs, MSE = %.6G" %(np.mean((M - Mhat)**2)))
14. 在 NumPy 中处理大型数组时,如何优化内存使用?
NumPy 有一个不太常用的功能 memmap()。它允许我们将数组存储为文件,从而读取超出内存大小的更大数组。其主要优点是惰性读取数据,在能够访问整个数据集的同时,降低整体内存占用。
巧妙地使用该函数,能让数据科学家更轻松、便捷地处理大规模数据。
import numpy as np
# Create a large array and save it to a file using memmap
filename = 'large_array.dat'
large_array_shape = (10000, 10000)
dtype = np.float32 # Specify the data type of the array
# Create a memmap object with the desired shape and dtype
large_array = np.memmap(filename, dtype=dtype, mode='w+', shape=large_array_shape)
# Initialize the array with some values (e.g., fill it with random numbers)
large_array[:] = np.random.rand(*large_array_shape)
# Access a small part of the array without loading the entire array into memory
sub_array = large_array[5000:5010, 5000:5010]
print(sub_array) # Output: A 10x10 array with random float values
# Clean up and ensure that the changes are written to disk
del large_array
15. 如何在 NumPy 中处理和操作包含缺失值或无穷值的数组?
处理缺失值与无穷值是数据科学中的常见任务。首先,您可以使用 NumPy 的 isnan() 或 isinf() 来找到这些缺失与无穷值。
如果存在系统性问题,我们可能需要检查管道;否则,可以考虑对这些值进行填充。
虽然可能不会直接用 NumPy 来填补缺失值,但通常会将 NumPy 函数与 pandas 的 fillna() 等方法结合使用来填充。例如,可以用 NumPy 的 mean() 或 median() 快速填补异常值。
面向数据科学家的 NumPy 面试题
到目前为止,我们讨论了通用的 NumPy 问题。之前的问题当然也适用于数据科学,但在本节中,我整理了专门面向数据科学家的 NumPy 问题。
16. 有没有办法快速、便捷地对二维数组的每一行或每一列应用函数?
有时我们需要在数组上执行自定义计算,以获得每行或每列的信息。幸运的是,可以使用 NumPy 的 apply_along_axis() 方法,将自定义函数应用于 NumPy 数组的某个轴上。函数会在数组的指定轴上整体应用。
import numpy as np
# Create a 2D array
data = np.array([
[1, 2, 3, 4, 5],
[10, 15, 20, 25, 30],
[100, 200, 300, 400, 500]
])
# Define a function to compute the range of a 1D array
def compute_range(arr):
return np.max(arr) - np.min(arr)
# Apply the compute_range function to each row (axis=1)
ranges = np.apply_along_axis(compute_range, axis=1, arr=data)
print("Range of each row:", ranges)
# Output:
# Range of each row: [ 4 20 400]
17. 如何利用 NumPy 对数据集进行特征缩放与归一化以用于机器学习?
对数据进行归一化能确保我们正确训练机器学习模型。若不归一化,量纲差异会影响模型结果,尤其是基于距离的模型。
我们可以使用 NumPy 的函数轻松完成缩放。以下是对所有列进行最小-最大缩放的示例。进行特征缩放时,请确保选择正确的维度。
import numpy as np
data = np.array([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
])
# Min-Max Scaling
min_vals = np.min(data, axis=0)
max_vals = np.max(data, axis=0)
scaled_data = (data - min_vals) / (max_vals - min_vals)
print("Scaled Data:\n", scaled_data)
# Output:
# Scaled Data:
# [[0. 0. 0. ]
# [0.5 0.5 0.5 ]
# [1. 1. 1. ]]
18. 有哪些方法可以轻松排序和索引我们的 NumPy 数组?
虽然类似 DataFrame 的 sort_values() 能排序,但在某些场景下我们需要找到这些排序值的位置。
NumPy 的 argsort() 会返回能将数组排序所需的索引位置。当我们需要对其他数据集进行正确的索引以与已排序的数组对齐时,这非常有用。通过获取这些位置,我们可以利用 argsort() 的输出来确保各数据集之间的一致性。
19. NumPy 的随机数生成器有哪一项重要特性可用于使结果可预测?为何重要?
计算机中的随机数并非真正随机,而是基于初始种子生成。由于我们常常希望测试数据并便于评估结果,就必须尽量减少管道中的随机性。
通过使用 NumPy 的 random.seed() 方法,我们可以为整个流程设置种子,从而每次获得相似结果。设置固定种子有助于我们判断效果提升是否源于模型调整,而非随机性。
20. 请描述如何用 NumPy 实现 K-Means。
面试中,您可能会被要求实现某种算法。这类问题的重点在于展现对模型与工具包的基本理解。
您无需死记下面的每一行代码,但应能指出关键步骤与所需方法。确保您已阅读过 K-Means(以及其他基础算法),并理解其工作原理。
import numpy as np
# Generate a sample dataset
np.random.seed(42) # For reproducibility
data = np.vstack([
np.random.normal(loc=[1, 1], scale=0.5, size=(50, 2)),
np.random.normal(loc=[5, 5], scale=0.5, size=(50, 2)),
np.random.normal(loc=[9, 1], scale=0.5, size=(50, 2))
])
def k_means(X, k, max_iters=100, tol=1e-4):
# Step 1: Initialize centroids randomly
num_samples, num_features = X.shape
centroids = X[np.random.choice(num_samples, k, replace=False)]
for i in range(max_iters):
# Step 2: Assign clusters
distances = np.linalg.norm(X[:, np.newaxis] - centroids, axis=2)
cluster_assignments = np.argmin(distances, axis=1)
# Step 3: Update centroids
new_centroids = np.array([X[cluster_assignments == j].mean(axis=0) for j in range(k)])
# Check for convergence
if np.all(np.linalg.norm(new_centroids - centroids, axis=1) < tol):
break
centroids = new_centroids
return centroids, cluster_assignments
# Apply k-means clustering
k = 3
centroids, cluster_assignments = k_means(data, k)
结语
用 NumPy 夯实面试知识,是迈向数据科学职业成功的关键步骤之一。
先从基础练习与理解入手,再进行具体实现。NumPy 用得越多,您就越能理解并内化其函数。试试 DataCamp 上的一些课程与教程,例如:
FAQs
数据科学面试还可能涉及哪些主题?
除了关键的 Python 编程概念外,熟悉 Matplotlib、scikit-learn 和 SciPy 等库也很重要。掌握这些工具能让您在数据科学面试中更具优势。
关于 NumPy 需要了解哪些关键点?
及时关注NumPy 的最新更新非常重要,了解新特性与变化有助于您在申请数据科学岗位时获得明显优势。
NumPy 的常见应用有哪些?
NumPy 在涉及矩阵计算的任务中至关重要,例如梯度下降与卷积神经网络的计算,因此在各种数据科学与机器学习场景中高度适用。
如何高效地学习 NumPy?
您可以通过使用 DataCamp 等平台上的资源并进行动手实践,快速、高效地学习 NumPy。实践应用是掌握 NumPy 的最有效方式。
有哪些适合练习 NumPy 的项目点子?
使用 NumPy 实现一个机器学习模型,是展示您数学功底与对该库理解的绝佳方式。可以从简单的 k-means 聚类开始,逐步过渡到更复杂的任务,如梯度下降。