最近在DataCamp上进修,对提高python脚本的效率有了更深的理解,并且也学会了很多方法。作为一个非科班已进门的小白,我最头疼的事莫过于取复杂结构数据的时候要写多层嵌套循环去拿data。直觉告诉我这不是一个高效的方法而且代码看上去不简洁,身边的人也说现在的硬件可以忽略脚本性能,但做科研出身的人是不可能不较真的,为此特意去看了一下这方面的内容也刚好碰到这节网课,以此篇记录一下所学,提升自己的业务代码,也供其他人参考一下。
0.思路
- 使用更高效的python包代替
for
循环 - 将不需要在循环中做处理的步骤移到循环体外
- 用更好的for遍历方式
1.测量方法
脚本的效率通过脚本运行时间和内存资源消耗进行衡量
- 如何检测脚本的效率:用时间和资源消耗去衡量
- 使用工具(魔法方法)计算脚本的内存和使用时间:%timeit、line_profiler(%lprun)、memory_profiler (%mprun)
2.使用场景(主要是消除循环)
列表
1.用map遍历处理list中的值
mylist = ['stress', 'luck', 'lost']
upper_list = list(map(str.upper, mylist))
print(upper_list)
['STRESS', 'LUCK', 'LOST']
2.用set比较列表
1.找出列表中的唯一值(这是set的属性)
list = [1, 2, 3, 3, 4]
print(set(list))
{1, 2, 3, 4}
2.比较两个列表
- 分别是找不同、找相同、并集、交集等
#找出两个列表中共有的集合
list_a = ['stress', 'luck', 'lost']
list_b = ['stress', 'luck', 'lost', 'always']
set_a = set(list_a)
set_b = set(list_b)
set_a.intersection(set_b)
#找出补集
set_b.difference(set_a)
{'always'}
#找出并集
set_a.union(set_b)
{'luck', 'lost', 'always', 'stress'}
Dataframe和Array
- 使用列表方法计算行列式
- numpy进行矢量化运算
- 尽量不使用
.iloc
的方法,而是使用各种迭代器(itertools):iterrows
、itertuple
、apply
、df.values
等遍历Dataframe中的值,通过.itertools
进行取值。
#列表方法统计每一行的和
myarray = [[1, 2, 3, 4],
[5, 6, 7, 8],
[2, 5, 6, 7]]
total_sum = [*map(sum, myarray)]
print(total_sum)
[10, 26, 20]
#使用numpy计算每一行的平均值
myarray_2 = np.array(myarray)
myarray_2_avg = myarray_2.mean(axis=1)
print(myarray_2_avg)
[2.5 6.5 5. ]
#用iterators对Dataframe的行进行循环迭代
for row_tuple in df.itertuples():
print(row_tuple)
Pandas(Index=0, a=1, b=2, c=3, d=4)
Pandas(Index=1, a=5, b=6, c=7, d=8)
Pandas(Index=2, a=2, b=5, c=6, d=7)
#元组可根据列名进行取值
for row_tuple in df.itertuples():
a = row_tuple.a
print(a)
1
5
2
#使用pandas对Dataframe里面行进行计算
df['difference'] = df['example'].values - df['example_2'].values
3.总结
- 消除不必要的for循环之后感觉代码看起来很舒服,减少了不必要的行数。写代码的时候也不是必须要完全规避掉
号外PS: DataCamp的课程是Harvard U进驻的课程有兴趣的小伙伴可以去看看(绝非广告,平台没打钱)
参考
DataCamp:Write efficient Python code
FreeCodeCamp
pandas文档
网友评论