jjzjj

生信log31|让Python代码高效(消除循环)的方法总结

周芷希Hazel 2023-10-08 原文

最近在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

  1. 使用列表方法计算行列式
  2. numpy进行矢量化运算
  3. 尽量不使用 .iloc的方法,而是使用各种迭代器(itertools):iterrowsitertupleapplydf.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文档

有关生信log31|让Python代码高效(消除循环)的方法总结的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  5. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  6. ruby - 树顶语法无限循环 - 2

    我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He

  7. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  8. Ruby 方法() 方法 - 2

    我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby​​-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco

  9. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  10. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

随机推荐