

大家好,我是正在实战各种AI项目的程序员晚枫。
欢迎来到数据分析课程第二课!
今天学习NumPy,这是Python科学计算的基础库。掌握它,你的数据处理速度能提升几十甚至上百倍。
为什么需要NumPy?
Python列表的问题
1 2 3 4 5 6 7 8
| import time
start = time.time() python_list = list(range(1000000)) result = [x * 2 for x in python_list] print(f"Python列表耗时: {time.time() - start:.4f}秒")
|
NumPy数组的优势
1 2 3 4 5 6 7
| import numpy as np
start = time.time() numpy_array = np.arange(1000000) result = numpy_array * 2 print(f"NumPy数组耗时: {time.time() - start:.4f}秒")
|
为什么这么快?
- NumPy底层用C语言实现
- 数组在内存中是连续的
- 支持向量化运算(不用写循环)
创建数组
从列表创建
1 2 3 4 5 6 7 8 9 10 11
| import numpy as np
arr1 = np.array([1, 2, 3, 4, 5]) print(arr1)
arr2 = np.array([[1, 2, 3], [4, 5, 6]]) print(arr2)
|
常用创建函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| np.arange(0, 10, 2) np.linspace(0, 1, 5)
np.zeros((3, 4)) np.ones((2, 3)) np.eye(3) np.full((2, 2), 7)
np.random.rand(3, 3) np.random.randint(1, 10, (3, 3)) np.random.randn(3, 3)
|
数组属性
1 2 3 4 5 6 7
| arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.shape) print(arr.ndim) print(arr.size) print(arr.dtype) print(arr.itemsize)
|
索引和切片
一维数组
1 2 3 4 5 6 7
| arr = np.array([10, 20, 30, 40, 50])
print(arr[0]) print(arr[-1]) print(arr[1:4]) print(arr[::2]) print(arr[::-1])
|
二维数组
1 2 3 4 5 6 7 8 9
| arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(arr[0, 1]) print(arr[0]) print(arr[:, 1]) print(arr[0:2, 1:3])
|
布尔索引(筛选)
1 2 3 4 5 6 7 8 9 10
| arr = np.array([1, 2, 3, 4, 5, 6])
print(arr[arr > 3])
print(arr[arr % 2 == 0])
print(arr[(arr > 2) & (arr < 6)])
|
数组运算
基本运算
1 2 3 4 5 6
| arr = np.array([1, 2, 3, 4, 5])
print(arr + 10) print(arr * 2) print(arr ** 2) print(arr / 2)
|
数组间运算
1 2 3 4 5 6
| a = np.array([1, 2, 3]) b = np.array([4, 5, 6])
print(a + b) print(a * b) print(a @ b)
|
通用函数(ufunc)
1 2 3 4 5 6 7
| arr = np.array([0, np.pi/2, np.pi])
print(np.sin(arr)) print(np.cos(arr)) print(np.exp(arr)) print(np.log(arr + 1)) print(np.sqrt(arr))
|
数组变形
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| arr = np.arange(12)
arr2d = arr.reshape(3, 4)
arr_flat = arr2d.flatten()
arr2d.T
|
实战:计算股票收益率
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import numpy as np
prices = np.array([100, 102, 101, 105, 108])
returns = (prices[1:] - prices[:-1]) / prices[:-1] print("日收益率:", returns)
cumulative_return = (prices[-1] - prices[0]) / prices[0] print(f"累计收益率: {cumulative_return:.2%}")
avg_return = np.mean(returns) print(f"平均日收益率: {avg_return:.2%}")
volatility = np.std(returns) print(f"波动率: {volatility:.2%}")
|
性能对比:NumPy vs Python列表
实际跑一下看看差距有多大:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import numpy as np import time
size = 10_000_000
start = time.time() py_list = list(range(size)) result = sum(py_list) print(f"Python列表: {time.time()-start:.4f}秒")
start = time.time() np_arr = np.arange(size) result = np.sum(np_arr) print(f"NumPy数组: {time.time()-start:.4f}秒")
|
不同数据类型的内存对比
1 2 3 4 5 6 7 8 9 10 11
| import sys
py_list = list(range(1000000)) np_arr = np.arange(1000000, dtype=np.int32)
print(f"Python列表: {sys.getsizeof(py_list) / 1024 / 1024:.1f} MB")
print(f"NumPy int32数组: {np_arr.nbytes / 1024 / 1024:.1f} MB")
|
进阶用法
广播机制详解
广播是NumPy最强大也最容易困惑的特性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| arr = np.array([[1, 2, 3], [4, 5, 6]]) print(arr + 10)
row = np.array([1, 2, 3]) col = np.array([[10], [20]]) print(row + col)
data = np.random.rand(100, 5) mean = data.mean(axis=0) std = data.std(axis=0) standardized = (data - mean) / std
|
花式索引
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| arr = np.arange(20).reshape(4, 5)
print(arr[[0, 2, 3]])
rows = np.array([0, 1, 2, 3]) cols = np.array([0, 2, 4]) print(arr[rows, cols])
print(arr[np.ix_([0, 2], [1, 3])])
|
避坑指南
❌ 坑1:视图vs副本搞混
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| arr = np.arange(6)
view = arr[1:4] view[0] = 999 print(arr)
copy = arr[1:4].copy() copy[0] = 100 print(arr)
print(view.base is not None) print(copy.base is not None)
|
❌ 坑2:整数数组索引的陷阱
1 2 3 4 5 6 7 8
| arr = np.arange(12).reshape(3, 4)
arr[[0, 1], [2, 3]] = 100
arr[[0, 1]] = 100
|
❌ 坑3:数据类型自动提升
1 2 3 4 5 6 7 8
| arr = np.array([1, 2, 3], dtype=np.int32) arr[0] = 1.5 print(arr)
arr = arr.astype(np.float64) arr[0] = 1.5 print(arr)
|
实战案例:分析电商用户消费数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import numpy as np
np.random.seed(42) user_ids = np.arange(1001, 2001) spend = np.random.exponential(500, 1000) orders = np.random.poisson(5, 1000) age = np.random.randint(18, 65, 1000)
print(f"平均消费: ¥{spend.mean():.0f}") print(f"消费中位数: ¥{np.median(spend):.0f}") print(f"消费标准差: ¥{spend.std():.0f}")
high_value = spend > np.percentile(spend, 80) print(f"高价值用户数: {high_value.sum()}") print(f"高价值用户平均消费: ¥{spend[high_value].mean():.0f}") print(f"普通用户平均消费: ¥{spend[~high_value].mean():.0f}")
young = age < 30 middle = (age >= 30) & (age < 45) senior = age >= 45 print(f"年轻人(<30)平均消费: ¥{spend[young].mean():.0f}") print(f"中年人(30-45)平均消费: ¥{spend[middle].mean():.0f}") print(f"年长者(>=45)平均消费: ¥{spend[senior].mean():.0f}")
avg_order_value = spend / np.maximum(orders, 1) print(f"平均客单价: ¥{avg_order_value.mean():.0f}")
|
下节预告
下一课我们将学习NumPy进阶-数学运算,包括统计函数、线性代数等内容。
👉 继续阅读:NumPy进阶-数学运算
💬 加入学习交流群
扫码加入Python学习交流群,和数千名同学一起进步:
👉 点击加入交流群
群里不定期分享:
- 数据分析实战案例
- Python学习资料
- 求职面试经验
- 行业最新动态
推荐:AI Python数据分析实战营
🎁 限时福利:送《利用Python进行数据分析》实体书
👉 点击了解详情
课程导航
上一篇: Anaconda安装与环境配置
下一篇: NumPy进阶-数学运算
PS:NumPy是数据分析的基石。花时间打好基础,后面的Pandas会学得更轻松。
📚 推荐教材
主教材:《Excel+Python 飞速搞定数据分析与处理(图灵出品)》
💬 联系我
主营业务:AI 编程培训、企业内训、技术咨询
🎓 AI 编程实战课程
想系统学习 AI 编程?程序员晚枫的 AI 编程实战课 帮你从零上手!