Python系列看到Part 2
先泼盆冷水:数据结构没用对,后面全白搭
花了整整一个下午拿Python跑一个某电商平台脱敏后的交易数据,100万行CSV。用list去存每条记录,再套两层for循环去做分组汇总,结果跑了快二十分钟没出结果。后来改成 dict 做分组键映射,配合 collections.defaultdict,速度直接降到两分钟以内。
from collections import defaultdict
# 糟糕的写法:list套list
result = []
for row in raw_data:
for item in result:
if item[0] == row["category"]:
item[1] += row["amount"]
break
else:
result.append([row["category"], row["amount"]])
# 正确的姿势:以dict的键来做聚合
total = defaultdict(float)
for row in raw_data:
total[row["category"]] += row["amount"]OOP在这里真的有用吗?
如果是刚上手做数据分析,我个人觉得不用急着套class。但有一种情况必须用——当你的数据清洗逻辑里包含多种状态流转、多个参数联动的时候。比如处理用户行为日志里的事件序列,写成一个 SessionProcessor 类,把清洗规则和状态属性封装在一起,比散落一地的函数舒服得多,也方便复用。
推导式是Python里最值得早点习惯的糖
列表推导式、字典推导式、集合推导式,这三个能极大压缩代码行数。最关键的是,跑同样逻辑时推导式比普通for循环快一些,因为底层做了优化:
# 普通循环
squared = []
for x in range(100):
if x % 2 == 0:
squared.append(x * x)
# 推导式
squared = [x * x for x in range(100) if x % 2 == 0]后来对比过同样处理一万条记录,推导式版本平均快了15%左右。
Pandas其实已经把这些都封装好了
说句大实话,真到了跑数据科学任务,我80%的时间都在用pandas的DataFrame,对象导向和原生数据结构其实用得不算多。但pandas报错的时候,不懂底层的Python数据结构是真的看不懂它在报什么。所以说,这一章内容虽然基础,但它是后面所有pandas、numpy操作能理解的前提。
顺带一提,Medium上这篇Part 2是付费的,我没看完全文原文。想白嫖完整版的话,可以直接跳去读Python官方文档的 Data Structures 和 Classes 两章,内容完全覆盖,而且更新更及时。
这个系列如果继续出Part 3,我猜会开始讲NumPy和Pandas实战了,到时候再看要不要跟着写一篇。
