深入解析NumPy中數(shù)組的核心概念與操作技巧
本節(jié)學(xué)習(xí)目標(biāo)
完成本節(jié)學(xué)習(xí)后,你將能夠:
- 理解 NumPy 數(shù)組(ndarray)與 Python 原生列表的本質(zhì)區(qū)別
- 熟練創(chuàng)建各種類型的 NumPy 數(shù)組
- 掌握 NumPy 的常用數(shù)據(jù)類型及其轉(zhuǎn)換方法
- 進(jìn)行數(shù)組的基本運(yùn)算和聚合操作
- 理解并運(yùn)用廣播機(jī)制
- 使用常用數(shù)學(xué)和統(tǒng)計(jì)函數(shù)處理數(shù)據(jù)
為什么學(xué)這個(gè)
如果把數(shù)據(jù)分析比作蓋房子,那么 NumPy 就是磚塊和水泥——它是最基礎(chǔ)、最重要的材料。
你可能聽說過 Python 的列表(list)也能存數(shù)據(jù),那為什么還要學(xué) NumPy?答案有兩個(gè)字:速度和功能。
速度對(duì)比:對(duì) 100 萬個(gè)數(shù)字求和,Python 列表需要約 50 毫秒,NumPy 數(shù)組只需要約 1 毫秒——快了 50 倍。如果數(shù)據(jù)量更大,差距會(huì)更驚人。
功能對(duì)比:Python 列表只能做簡(jiǎn)單的存儲(chǔ)和遍歷,而 NumPy 數(shù)組支持矩陣運(yùn)算、統(tǒng)計(jì)分析、線性代數(shù)等高級(jí)操作。
比喻:Python 列表像一個(gè)普通收納盒,什么都能裝,但找東西慢;NumPy 數(shù)組像一個(gè)智能收納柜,不僅存得快,還能自動(dòng)幫你分類、計(jì)算和查找。
事實(shí)上,幾乎所有主流的數(shù)據(jù)分析庫(pandas、scikit-learn、SciPy、TensorFlow)底層都依賴 NumPy。學(xué)好 NumPy,就等于掌握了整個(gè)數(shù)據(jù)分析生態(tài)的"通用語言"。
認(rèn)識(shí) ndarray——NumPy 的核心數(shù)據(jù)結(jié)構(gòu)
什么是 ndarray
ndarray(N-dimensional array)是 NumPy 的核心對(duì)象,即 N 維數(shù)組。它是一個(gè)存儲(chǔ)同類型數(shù)據(jù)的多維容器。
與 Python 列表的區(qū)別:
| 特性 | Python list | NumPy ndarray |
|---|---|---|
| 數(shù)據(jù)類型 | 可以混合 | 必須統(tǒng)一 |
| 運(yùn)算方式 | 需要循環(huán) | 支持向量化 |
| 內(nèi)存占用 | 較大 | 緊湊 |
| 執(zhí)行速度 | 較慢 | 極快 |
| 功能 | 基礎(chǔ) | 豐富 |
為什么 ndarray 這么快
- 內(nèi)存連續(xù)存儲(chǔ):所有元素在內(nèi)存中緊挨著存放,CPU 可以高效讀?。愃茢?shù)組的"緩存友好"特性)
- C 語言底層實(shí)現(xiàn):核心運(yùn)算由 C 語言編寫,繞過了 Python 的解釋器開銷
- 并行計(jì)算優(yōu)化:底層利用了 CPU 的 SIMD(單指令多數(shù)據(jù))指令集
ndarray 的三個(gè)核心屬性
import numpy as np
# 創(chuàng)建一個(gè)二維數(shù)組
arr = np.array([[1, 2, 3],
[4, 5, 6]])
print("數(shù)組內(nèi)容:")
print(arr)
print(f"\n維度數(shù)量 (ndim): {arr.ndim}")
print(f"形狀 (shape): {arr.shape}")
print(f"元素總數(shù) (size): {arr.size}")
print(f"數(shù)據(jù)類型 (dtype): {arr.dtype}")
print(f"每個(gè)元素占字節(jié)數(shù) (itemsize): {arr.itemsize}")
print(f"總內(nèi)存占用 (nbytes): {arr.nbytes}")
輸出結(jié)果:
數(shù)組內(nèi)容:
[[1 2 3]
[4 5 6]]
維度數(shù)量 (ndim): 2
形狀 (shape): (2, 3)
元素總數(shù) (size): 6
數(shù)據(jù)類型 (dtype): int32 (或 int64,取決于系統(tǒng))
每個(gè)元素占字節(jié)數(shù) (itemsize): 4
總內(nèi)存占用 (nbytes): 24
理解 shape:(2, 3) 表示這個(gè)數(shù)組有 2 行、3 列。類比Excel表格,就是 2 行 3 列的數(shù)據(jù)區(qū)域。
NumPy 數(shù)組的創(chuàng)建方式
方式1:從 Python 列表/元組創(chuàng)建
# 從列表創(chuàng)建一維數(shù)組
arr1 = np.array([1, 2, 3, 4, 5])
print("一維數(shù)組:", arr1)
# 從嵌套列表創(chuàng)建二維數(shù)組
arr2 = np.array([[1, 2, 3],
[4, 5, 6]])
print("二維數(shù)組:\n", arr2)
# 從元組創(chuàng)建
arr3 = np.array((10, 20, 30))
print("從元組創(chuàng)建:", arr3)
# 指定數(shù)據(jù)類型
arr4 = np.array([1, 2, 3], dtype=np.float64)
print("指定浮點(diǎn)類型:", arr4)
方式2:使用內(nèi)置函數(shù)創(chuàng)建特殊數(shù)組
# 全零數(shù)組
zeros = np.zeros((3, 4))
print("3x4 全零數(shù)組:\n", zeros)
# 全一數(shù)組
ones = np.ones((2, 3))
print("2x3 全一數(shù)組:\n", ones)
# 指定值的數(shù)組
full = np.full((2, 2), 7)
print("2x2 填充7的數(shù)組:\n", full)
# 單位矩陣(對(duì)角線為1,其余為0)
eye = np.eye(3)
print("3x3 單位矩陣:\n", eye)
# 對(duì)角矩陣
diag = np.diag([1, 2, 3])
print("對(duì)角矩陣:\n", diag)
方式3:生成數(shù)值序列
# arange:類似 range,但返回?cái)?shù)組
print("arange(10):", np.arange(10))
print("arange(2, 10, 2):", np.arange(2, 10, 2))
# 輸出: [2 4 6 8]
# linspace:生成等間距數(shù)列(包含終點(diǎn))
print("linspace(0, 1, 5):", np.linspace(0, 1, 5))
# 輸出: [0. 0.25 0.5 0.75 1. ]
# logspace:生成等比數(shù)列
print("logspace(0, 2, 5):", np.logspace(0, 2, 5))
# 輸出: [ 1. 3.16 10. 31.6 100. ]
# 實(shí)際應(yīng)用場(chǎng)景:生成 x 軸坐標(biāo)用于畫圖
x = np.linspace(-np.pi, np.pi, 100) # -π 到 π,100個(gè)點(diǎn)
print(f"用于繪圖的 x 軸: {len(x)} 個(gè)點(diǎn)")
方式4:生成隨機(jī)數(shù)組
np.random.seed(42) # 設(shè)置隨機(jī)種子,保證結(jié)果可復(fù)現(xiàn)
# 均勻分布 [0, 1)
rand_uniform = np.random.rand(3, 3)
print("均勻分布隨機(jī)數(shù)組:\n", rand_uniform)
# 標(biāo)準(zhǔn)正態(tài)分布(均值0,標(biāo)準(zhǔn)差1)
rand_normal = np.random.randn(3, 3)
print("標(biāo)準(zhǔn)正態(tài)分布:\n", rand_normal)
# 指定范圍的整數(shù)
rand_int = np.random.randint(1, 100, size=(3, 4))
print("1~99 的隨機(jī)整數(shù):\n", rand_int)
# 從指定數(shù)組中隨機(jī)選擇
choices = np.random.choice(['A', 'B', 'C', 'D'], size=10)
print("隨機(jī)選擇:", choices)
# 實(shí)際應(yīng)用:模擬擲骰子 1000 次
dice_rolls = np.random.randint(1, 7, size=1000)
print(f"骰子平均點(diǎn)數(shù): {dice_rolls.mean():.2f}") # 理論值應(yīng)接近 3.5
實(shí)際場(chǎng)景:隨機(jī)數(shù)在數(shù)據(jù)分析中用途廣泛——模擬數(shù)據(jù)、A/B 測(cè)試、隨機(jī)抽樣、機(jī)器學(xué)習(xí)中的權(quán)重初始化等。
NumPy 數(shù)據(jù)類型
常用數(shù)據(jù)類型一覽
# 整數(shù)類型 print(np.int8(127)) # -128 ~ 127 print(np.int16(32767)) # -32768 ~ 32767 print(np.int32(2147483647)) print(np.int64(9223372036854775807)) # 無符號(hào)整數(shù)(只存正數(shù)) print(np.uint8(255)) # 0 ~ 255 # 浮點(diǎn)數(shù)類型 print(np.float16(3.14)) # 半精度,范圍小 print(np.float32(3.14159)) print(np.float64(3.14159265358979)) # 默認(rèn)浮點(diǎn)類型 # 布爾類型 print(np.bool_(True)) # 字符串類型 print(np.array(['hello', 'world'], dtype='U5')) # 最多5個(gè)字符
數(shù)據(jù)類型轉(zhuǎn)換
arr = np.array([1, 2, 3, 4, 5])
print(f"原始類型: {arr.dtype}") # int32 或 int64
# 轉(zhuǎn)換為浮點(diǎn)數(shù)
arr_float = arr.astype(np.float64)
print(f"轉(zhuǎn)換為浮點(diǎn): {arr_float.dtype}")
# 轉(zhuǎn)換為布爾值
arr_bool = arr.astype(bool)
print(f"轉(zhuǎn)換為布爾: {arr_bool}")
# 轉(zhuǎn)換為字符串
arr_str = arr.astype(str)
print(f"轉(zhuǎn)換為字符串: {arr_str}")
# 注意:精度丟失
arr_big = np.array([1.7, 2.9, 3.1])
arr_int = arr_big.astype(np.int32)
print(f"浮點(diǎn)轉(zhuǎn)整數(shù)(截?cái)?: {arr_int}") # [1 2 3],注意不是四舍五入
數(shù)組的基本運(yùn)算
算術(shù)運(yùn)算
a = np.array([10, 20, 30, 40])
b = np.array([1, 2, 3, 4])
# 逐元素運(yùn)算
print("加法:", a + b) # [11 22 33 44]
print("減法:", a - b) # [ 9 18 27 36]
print("乘法:", a * b) # [10 40 90 160]
print("除法:", a / b) # [10. 10. 10. 10.]
print("整除:", a // b) # [10 10 10 10]
print("取余:", a % b) # [0 0 0 0]
print("冪運(yùn)算:", a ** 2) # [ 100 400 900 1600]
# 數(shù)組與標(biāo)量運(yùn)算
print("加5:", a + 5) # [15 25 35 45]
print("乘2:", a * 2) # [20 40 60 80]
比較運(yùn)算
a = np.array([10, 20, 30, 40, 50])
# 比較運(yùn)算返回布爾數(shù)組
print("大于25:", a > 25) # [False False True True True]
print("等于30:", a == 30) # [False False True False False]
print("不等于20:", a != 20) # [ True False True True True]
print("在20~40之間:", (a >= 20) & (a <= 40))
# [False True True True False]
聚合(統(tǒng)計(jì))運(yùn)算
scores = np.array([85, 92, 78, 96, 88, 73, 95, 81])
print(f"總分: {scores.sum()}")
print(f"平均分: {scores.mean()}")
print(f"標(biāo)準(zhǔn)差: {scores.std():.2f}")
print(f"方差: {scores.var():.2f}")
print(f"最高分: {scores.max()}")
print(f"最低分: {scores.min()}")
print(f"最高分索引: {scores.argmax()}")
print(f"最低分索引: {scores.argmin()}")
print(f"中位數(shù): {np.median(scores)}")
print(f"累計(jì)和: {scores.cumsum()}")
多維數(shù)組的軸(axis)概念
matrix = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print("原始矩陣:")
print(matrix)
# axis=0 表示按列(沿著行的方向)
print("\n按列求和 (axis=0):", matrix.sum(axis=0)) # [12 15 18]
# axis=1 表示按行(沿著列的方向)
print("按行求和 (axis=1):", matrix.sum(axis=1)) # [ 6 15 24]
# 不指定 axis 表示對(duì)所有元素
print("全部求和:", matrix.sum()) # 45
# 其他聚合函數(shù)同樣支持 axis
print("\n每列最大值:", matrix.max(axis=0))
print("每行平均值:", matrix.mean(axis=1))
理解 axis 的技巧:axis=N 表示"沿著第 N 個(gè)維度進(jìn)行壓縮"。axis=0 就是把"行"壓扁,結(jié)果是每列的統(tǒng)計(jì)值;axis=1 就是把"列"壓扁,結(jié)果是每行的統(tǒng)計(jì)值。就像用復(fù)印機(jī)掃描,掃描方向就是被壓扁的方向。
數(shù)組的索引與切片
一維數(shù)組索引
arr = np.array([10, 20, 30, 40, 50, 60])
# 正向索引(從 0 開始)
print("第1個(gè)元素:", arr[0]) # 10
print("第3個(gè)元素:", arr[2]) # 30
# 負(fù)向索引(從 -1 開始,表示倒數(shù))
print("最后一個(gè)元素:", arr[-1]) # 60
print("倒數(shù)第2個(gè):", arr[-2]) # 50
# 切片 [start:stop:step]
print("前3個(gè):", arr[:3]) # [10 20 30]
print("從第3個(gè)開始:", arr[2:]) # [30 40 50 60]
print("每隔一個(gè):", arr[::2]) # [10 30 50]
print("反轉(zhuǎn):", arr[::-1]) # [60 50 40 30 20 10]
二維數(shù)組索引
matrix = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
# [行, 列] 索引
print("第2行第3列:", matrix[1, 2]) # 7
# 行切片
print("第1行:", matrix[0]) # [1 2 3 4]
print("前兩行:\n", matrix[:2])
# 列切片
print("第2列:", matrix[:, 1]) # [2 6 10]
print("第2~3列:\n", matrix[:, 1:3])
# 行列同時(shí)切片
print("中間2x2區(qū)域:\n", matrix[1:3, 1:3])
# [[ 6 7]
# [10 11]]
# 重要:切片返回的是視圖(共享內(nèi)存),修改會(huì)影響原數(shù)組
sub = matrix[:2, :2]
sub[0, 0] = 999
print("修改切片后原數(shù)組:\n", matrix)
# 第1行第1列變?yōu)?999
# 如果需要副本,使用 .copy()
sub_copy = matrix[:2, :2].copy()
sub_copy[0, 0] = 0
print("修改副本后原數(shù)組不變:", matrix[0, 0]) # 仍是 999
廣播機(jī)制(Broadcasting)——NumPy 的魔法
什么是廣播
廣播是 NumPy 對(duì)不同形狀數(shù)組進(jìn)行運(yùn)算時(shí)的一種自動(dòng)擴(kuò)展機(jī)制。它讓不同大小的數(shù)組也能"配對(duì)"運(yùn)算。
比喻:廣播就像拼圖時(shí)的"自動(dòng)適配"——如果你有一塊大畫布和一個(gè)小印章,廣播會(huì)自動(dòng)把印章在畫布上重復(fù)蓋,直到覆蓋整個(gè)畫布。
廣播規(guī)則
- 如果兩個(gè)數(shù)組維度數(shù)不同,在維度較少的數(shù)組前面補(bǔ) 1
- 如果某個(gè)維度上大小不同,且其中一個(gè)為 1,則該維度可擴(kuò)展以匹配另一個(gè)
- 如果某個(gè)維度上大小不同,且都不為 1,則無法廣播(報(bào)錯(cuò))
代碼示例
# 場(chǎng)景1:數(shù)組 + 標(biāo)量(最簡(jiǎn)單的廣播)
arr = np.array([1, 2, 3])
print("數(shù)組 + 10:", arr + 10) # [11 12 13]
# 內(nèi)部過程: 10 被廣播為 [10, 10, 10]
# 場(chǎng)景2:二維數(shù)組 + 一維數(shù)組
matrix = np.array([[1, 2, 3],
[4, 5, 6]])
row_add = np.array([10, 20, 30])
print("每行加 [10,20,30]:")
print(matrix + row_add)
# [[11 22 33]
# [14 25 36]]
# 場(chǎng)景3:列向量 + 行向量(生成矩陣)
col = np.array([[1], [2], [3]]) # 形狀 (3, 1)
row = np.array([10, 20, 30]) # 形狀 (3,)
print("列向量 + 行向量 (廣播生成矩陣):")
print(col + row)
# [[11 21 31]
# [12 22 32]
# [13 23 33]]
# 場(chǎng)景4:實(shí)際應(yīng)用——成績(jī)標(biāo)準(zhǔn)化
scores = np.array([[85, 90, 78],
[92, 88, 95],
[76, 82, 88]])
mean_per_subject = scores.mean(axis=0) # 每科平均分
print("每科平均分:", mean_per_subject)
# 每個(gè)學(xué)生每科減去該科平均分(廣播)
centered = scores - mean_per_subject
print("中心化后的分?jǐn)?shù):\n", np.round(centered, 1))
廣播失敗的情況
# 這種情況無法廣播
try:
a = np.array([[1, 2, 3], # 形狀 (2, 3)
[4, 5, 6]])
b = np.array([1, 2]) # 形狀 (2,)
result = a + b
except ValueError as e:
print("廣播失敗:", e)
# 原因: 最后一維度 3 != 2,且都不是 1
常用數(shù)學(xué)函數(shù)
x = np.array([0, np.pi/6, np.pi/4, np.pi/3, np.pi/2])
# 三角函數(shù)
print("sin(x):", np.sin(x))
print("cos(x):", np.round(np.cos(x), 4))
print("tan(x):", np.round(np.tan(x), 4))
# 指數(shù)和對(duì)數(shù)
print("\ne^x:", np.round(np.exp(x), 4))
print("ln(x+1):", np.round(np.log(x + 1), 4))
print("log10(x+1):", np.round(np.log10(x + 1), 4))
# 舍入函數(shù)
numbers = np.array([1.2, 2.5, 3.7, 4.49, 5.5])
print("\n原始數(shù)據(jù):", numbers)
print("四舍五入:", np.round(numbers))
print("向上取整:", np.ceil(numbers))
print("向下取整:", np.floor(numbers))
print("截?cái)嗳≌?", np.trunc(numbers))
# 絕對(duì)值和符號(hào)
neg = np.array([-3, -2, -1, 0, 1, 2, 3])
print("\n絕對(duì)值:", np.abs(neg))
print("符號(hào)函數(shù):", np.sign(neg))
代碼示例:綜合實(shí)戰(zhàn)
實(shí)戰(zhàn)1:學(xué)生成績(jī)分析系統(tǒng)
import numpy as np
# 模擬一個(gè)班級(jí)30名學(xué)生、5門課程的成績(jī)
np.random.seed(42)
n_students = 30
n_subjects = 5
subjects = ['語文', '數(shù)學(xué)', '英語', '物理', '化學(xué)']
# 生成成績(jī)(正態(tài)分布,均值70,標(biāo)準(zhǔn)差15)
scores = np.random.normal(70, 15, (n_students, n_subjects))
scores = np.clip(scores, 0, 100) # 限制在0~100之間
scores = np.round(scores, 1)
print("=" * 50)
print("學(xué)生成績(jī)分析系統(tǒng)")
print("=" * 50)
# 1. 每科的基本統(tǒng)計(jì)
print("\n各科統(tǒng)計(jì):")
for i, subject in enumerate(subjects):
col = scores[:, i]
print(f" {subject}: 平均={col.mean():.1f}, "
f"最高={col.max():.1f}, 最低={col.min():.1f}, "
f"標(biāo)準(zhǔn)差={col.std():.1f}")
# 2. 每個(gè)學(xué)生的總分和平均分
total_scores = scores.sum(axis=1)
avg_scores = scores.mean(axis=1)
print(f"\n班級(jí)總平均分: {avg_scores.mean():.1f}")
print(f"最高總分: {total_scores.max():.1f}")
print(f"最低總分: {total_scores.min():.1f}")
# 3. 找出每科最高分的學(xué)生
for i, subject in enumerate(subjects):
best_student = scores[:, i].argmax()
print(f" {subject}最高分: 學(xué)生{best_student+1}號(hào) ({scores[best_student, i]}分)")
# 4. 成績(jī)分布分析
print(f"\n成績(jī)等級(jí)分布:")
def get_grade(score):
if score >= 90: return '優(yōu)秀'
elif score >= 80: return '良好'
elif score >= 60: return '及格'
else: return '不及格'
grades_flat = np.array([get_grade(s) for s in scores.flatten()])
for grade in ['優(yōu)秀', '良好', '及格', '不及格']:
count = (grades_flat == grade).sum()
pct = count / len(grades_flat) * 100
print(f" {grade}: {count}人 ({pct:.1f}%)")
實(shí)戰(zhàn)2:矩陣運(yùn)算——圖像灰度處理
import numpy as np
# 模擬一張 4x4 的 RGB 圖像(每個(gè)像素有 R, G, B 三個(gè)通道)
# 形狀: (高, 寬, 通道數(shù))
np.random.seed(42)
image = np.random.randint(0, 256, (4, 4, 3), dtype=np.uint8)
print("原始RGB圖像 (4x4):")
print(image[:, :, 0]) # 顯示 R 通道
# 灰度轉(zhuǎn)換公式: Gray = 0.299*R + 0.587*G + 0.114*B
weights = np.array([0.299, 0.587, 0.114])
# 使用點(diǎn)積進(jìn)行灰度轉(zhuǎn)換(廣播)
gray = np.dot(image, weights)
gray = np.round(gray).astype(np.uint8)
print("\n灰度圖像:")
print(gray)
# 二值化處理:設(shè)定閾值128
binary = (gray > 128).astype(np.uint8) * 255
print("\n二值化圖像 (閾值128):")
print(binary)
實(shí)戰(zhàn)練習(xí)
練習(xí)1:數(shù)組創(chuàng)建基礎(chǔ)
題目:創(chuàng)建以下數(shù)組:
- 一個(gè)包含 0~9 的一維數(shù)組
- 一個(gè) 3 行 4 列的全 1 數(shù)組
- 一個(gè) 4 行 4 列的單位矩陣
- 1~100 中所有 3 的倍數(shù)構(gòu)成的數(shù)組
參考答案:
# 1. 0~9 arr1 = np.arange(10) print(arr1) # 2. 3x4 全1 arr2 = np.ones((3, 4)) print(arr2) # 3. 4x4 單位矩陣 arr3 = np.eye(4) print(arr3) # 4. 1~100中3的倍數(shù) multiples = np.arange(3, 101, 3) print(multiples)
練習(xí)2:統(tǒng)計(jì)分析
題目:某店鋪一周七天的營(yíng)業(yè)額為 [1200, 1500, 1800, 1350, 2100, 2800, 2500],請(qǐng)計(jì)算:
- 日均營(yíng)業(yè)額
- 營(yíng)業(yè)額的標(biāo)準(zhǔn)差(波動(dòng)程度)
- 哪幾天高于日均?
- 如果保持日均水平,一個(gè)月(30天)預(yù)計(jì)收入多少?
參考答案:
revenue = np.array([1200, 1500, 1800, 1350, 2100, 2800, 2500])
# 1. 日均
daily_avg = revenue.mean()
print(f"日均營(yíng)業(yè)額: {daily_avg:.2f}元")
# 2. 標(biāo)準(zhǔn)差
std = revenue.std()
print(f"營(yíng)業(yè)額標(biāo)準(zhǔn)差: {std:.2f}元")
# 3. 高于日均的日期
above_avg = revenue > daily_avg
days = np.array(['周一', '周二', '周三', '周四', '周五', '周六', '周日'])
print(f"高于日均的日子: {days[above_avg]}")
# 4. 月度預(yù)估
monthly = daily_avg * 30
print(f"月度預(yù)估: {monthly:.2f}元")
練習(xí)3:廣播機(jī)制應(yīng)用
題目:有一個(gè) 5 行 3 列的成績(jī)矩陣(5個(gè)學(xué)生,3門課),請(qǐng)使用廣播完成:
- 將每個(gè)學(xué)生的成績(jī)減去該學(xué)生的平均分(學(xué)生維度的中心化)
- 將每門課的成績(jī)除以該門課的最高分(歸一化到 0~1)
參考答案:
scores = np.array([[85, 90, 78],
[92, 88, 95],
[76, 82, 88],
[95, 91, 89],
[70, 75, 80]])
# 1. 減去每個(gè)學(xué)生自己的平均分(按行求均值,保持維度)
row_mean = scores.mean(axis=1, keepdims=True)
centered = scores - row_mean
print("學(xué)生維度中心化:")
print(np.round(centered, 1))
# 2. 歸一化到 0~1(每列除以該列最大值)
col_max = scores.max(axis=0)
normalized = scores / col_max
print("\n歸一化 (0~1):")
print(np.round(normalized, 3))
練習(xí)4:向量化思維訓(xùn)練
題目:不使用任何 for 循環(huán),用 NumPy 計(jì)算 1~1000 中所有偶數(shù)的平方和。
參考答案:
# 方法:先篩選偶數(shù),再平方,再求和
numbers = np.arange(1, 1001)
even_numbers = numbers[numbers % 2 == 0]
result = (even_numbers ** 2).sum()
print(f"1~1000中所有偶數(shù)的平方和: {result}")
# 一行寫法
print(np.sum(np.arange(2, 1001, 2) ** 2))
本節(jié)總結(jié)
本節(jié)我們深入學(xué)習(xí)了 NumPy 的核心知識(shí)。重點(diǎn)回顧:
- ndarray 是 NumPy 的核心:理解
ndim、shape、dtype、size四個(gè)屬性是掌握 NumPy 的第一步。 - 數(shù)組創(chuàng)建方式多樣:從列表轉(zhuǎn)換、內(nèi)置函數(shù)(zeros/ones/arange/linspace)、隨機(jī)生成,根據(jù)場(chǎng)景靈活選擇。
- 數(shù)據(jù)類型統(tǒng)一且緊湊:通過
dtype和astype()控制數(shù)據(jù)類型,在精度和內(nèi)存之間做權(quán)衡。 - 向量化運(yùn)算替代循環(huán):NumPy 的算術(shù)運(yùn)算都是逐元素進(jìn)行的,不需要寫 for 循環(huán)。
- 廣播是高級(jí)運(yùn)算的關(guān)鍵:理解廣播規(guī)則后,可以輕松實(shí)現(xiàn)復(fù)雜的矩陣操作,代碼簡(jiǎn)潔高效。
- 聚合運(yùn)算配合 axis:
axis=0按列、axis=1按行,這是處理多維數(shù)據(jù)的基本功。
記住一句話:在 NumPy 的世界里,沒有循環(huán),只有數(shù)組。這是從"程序員思維"到"數(shù)據(jù)分析思維"的重要轉(zhuǎn)變。
到此這篇關(guān)于深入解析NumPy中數(shù)組的核心概念與操作技巧的文章就介紹到這了,更多相關(guān)NumPy數(shù)組操作內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python采用getopt解析命令行輸入?yún)?shù)實(shí)例
這篇文章主要介紹了python采用getopt解析命令行輸入?yún)?shù)實(shí)例,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2014-09-09
Python實(shí)現(xiàn)Excel表內(nèi)關(guān)鍵字查修改刪
在日常辦公和數(shù)據(jù)處理中,Excel作為最常用的表格工具,承載著海量業(yè)務(wù)數(shù)據(jù),但對(duì)于有些場(chǎng)景也會(huì)力不從心,本文將使用Python開發(fā)一個(gè)Excel表內(nèi)關(guān)鍵字查修改刪工具,需要的可以參考下2025-04-04
Python PyQt5標(biāo)準(zhǔn)對(duì)話框用法示例
這篇文章主要介紹了Python PyQt5標(biāo)準(zhǔn)對(duì)話框用法,結(jié)合實(shí)例形式分析了PyQt5常用的標(biāo)準(zhǔn)對(duì)話框及相關(guān)使用技巧,需要的朋友可以參考下2017-08-08
對(duì)python 生成拼接xml報(bào)文的示例詳解
今天小編就為大家分享一篇對(duì)python 生成拼接xml報(bào)文的示例詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-12-12
Django之創(chuàng)建引擎索引報(bào)錯(cuò)及解決詳解
這篇文章主要介紹了Django之創(chuàng)建引擎索引報(bào)錯(cuò)及解決詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07
python使用生成器實(shí)現(xiàn)可迭代對(duì)象
這篇文章主要為大家詳細(xì)介紹了python如何使用生成器實(shí)現(xiàn)可迭代對(duì)象,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03
Python數(shù)據(jù)可視化:冪律分布實(shí)例詳解
Django處理Ajax發(fā)送的Get請(qǐng)求代碼詳解

