Courses
NumPyは、データサイエンティストのツールキットにおける基本要素です。大量データであっても、Pythonで効率的に処理できます。
NumPyが提供するツールセット(要素ごとの簡単な計算、行列積、ベクトル化など)は、Pythonで複雑な計算を行ううえで最有力の選択肢にします。そのため、面接でも頻繁に取り上げられます。本記事を読んで、想定される質問を復習しておきましょう。
NumPyを実践的に学べる追加リソースも、DataCampでぜひチェックしてください。
基礎的なNumPyの面接質問
以下の基礎質問で、NumPyの基本を理解しているかを確認しましょう。ウォームアップとして最適で、NumPyの機能と目的を押さえられます。
1. NumPyとは何か、そしてデータサイエンスで使われる理由は?
NumPyは、パフォーマンス上の理由から多くの部分がC/C++で実装されたPythonパッケージです。主な目的は、Pythonで大規模なデータ配列の計算をより高速かつ容易にすることです。 その中核機能は以下のとおりです。
- 大規模な多次元配列や行列をサポートし、巨大なデータセットを扱えるようにします。
- これらの配列に対して効率的に動作する包括的な数学関数群を提供し、大規模データの高速計算を可能にします。
- NumPyのベクトル化された演算により、複雑な数値演算を効率的に実行できます。
- pandas、scikit-learn、SciPyなど多くのデータサイエンス向けライブラリの土台であり、Pythonのデータサイエンスエコシステムの要です。
- NumPy配列はPythonのリストよりもメモリ効率が高く、ビッグデータを扱う際に重要です。
2. NumPyで1次元配列をどのように作成しますか?
NumPy配列の作成はとても簡単です。array()メソッドを呼び出して配列オブジェクトを作成します。1次元配列の作り方を理解すれば、より高次元の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配列の形状確認は重要です。データ処理の過程で、最終的な出力配列サイズの期待値があることが多いからです。
結果が期待に合わない場合、配列のshapeを確認することで問題解決に向けた対応が可能になります。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. NumPy配列をどのようにリシェイプ(reshape)しますか?
配列のリシェイプは、前処理や特徴量エンジニアリングでよく行う操作です。さまざまなアルゴリズムの入力要件に合わせたり、分析のためにデータを再編成したりするのに不可欠です。
reshape()メソッドまたはnp.reshape()関数で配列をリシェイプできます。例は次のとおりです。
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で計算を行うことが求められます。
6. すべてがゼロ、またはすべてが1の配列をどのように作成しますか?
ゼロや1で埋められた配列は、行列の初期化、マスク配列の作成、プレースホルダのデータ構造の準備など、多くのデータサイエンス作業で必要になります。
NumPyで全ゼロまたは全1の配列を作るには、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におけるブロードキャストとは何ですか?
ブロードキャストは、サイズの異なる配列間で効率的に演算できるようにする、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つの入力を受け取ります。
- 最初の引数は任意のブール式
- 2つ目は条件が真のときの結果
- 3つ目は条件が偽のときの結果
10. 二乗平均平方根誤差(MSE)のような計算にNumPyをどのように活用できますか?
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にはあまり知られていない「ストライド」という機能があります。ストライドの1つの実装として、配列のスライディングウィンドウビューを作れます。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単独で行わないこともありますが、pandasのfillna()などとNumPy関数を組み合わせて行うことが多いです。たとえばNumPyのmean()やmedian()を使って、誤った値を迅速に補完できます。
データサイエンティスト向けのNumPy面接質問
ここまでは一般的なNumPyの質問を扱いました。もちろん、これまでの質問もデータサイエンスに当てはまりますが、このセクションではデータサイエンティストに特化したNumPyの質問をまとめました。
16. 2次元配列の各行・各列に関数を素早く簡単に適用する方法はありますか?
配列に対してカスタム計算を行い、各行や各列の情報を取得したいことがあります。NumPyのapply_along_axis()を使えば、配列全体の特定の軸に沿ってカスタム関数を適用できます。
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クラスタリングのようなシンプルなプロジェクトから始め、勾配降下法のようなより複雑な課題へと進みましょう。