【问题标题】:Slow iteration with pandas大熊猫的慢迭代
【发布时间】:2021-10-22 23:13:46
【问题描述】:

我正在使用以下代码生成包含 6 个或更少元素的所有和弦,每个元素有 12 个可能的音符。所以生成的和弦数量应该是:(12 * 12 * 12 * 12 * 12 * 12) + (12 * 12 * 12 * 12 * 12) + (12 * 12 * 12 * 12) + (12 * 12 * 12) + (12 * 12) + (12) = 3.257.436。对吧?

如果处理速度随时间变化,我相信我的笔记本需要 30 个小时才能完成……我在 google cloud 上创建了一个免费的虚拟机(8 个 vCpus,8gb de ram)并执行了脚本,但是已经快 4 小时了。

所以我在想是否有办法加快这个过程。我无法使用具有 16 个 vCpus 的 Vms。而且我不知道我可以做些什么来改进我的脚本。

def calculando_todos_acordes_e_diferencas():
    import pandas as pd
    import itertools                          
    anagrama=[]
    for i in range(1,13):
        anagrama.append(i)

    tst=[[[0],[0]]]
    df=pd.DataFrame(tst, columns=["notas","diferencas"])
    count_name=-1

    for qntd_notas in range(7):
        for i in itertools.product((anagrama), repeat=qntd_notas) :
            diferencas=[]
            count=-1
            for primeiro in i :
                count=count+1
        
        
                if i.index(primeiro) != len(i)-1 :
                    for segundo in i[count+1:]:
                        diferenca= segundo - primeiro
                        if diferenca < 0 :
                            diferenca=diferenca* -1
                        diferencas.append(diferenca)

          #  if len(df.index) == 100000 :
           #     count_name=count_name+1
            #    df=df.append({"notas":list(i),"diferencas":diferencas},ignore_index=True)
             #   df.to_csv("acordes e diferencas pt %s.csv" %(count_name), index=False)
              #  df=pd.DataFrame(tst, columns=["notas","diferencas"])

            df=df.append({"notas":list(i),"diferencas":diferencas},ignore_index=True)
    
    df.to_csv("acordes e diferencas TOTAL2.csv", index=False)
            #else:
            
     
calculando_todos_acordes_e_diferencas()

【问题讨论】:

  • 如果你能找到一种方法来避免 python 中的实际循环,事情会更快。否则,您可以查看 cython 是否适合您。

标签: python-3.x pandas iterator hardware


【解决方案1】:

如果我理解正确,您想要的是 1-6 组大小的所有笔记的组合。这不会产生 320 万个可能性,而只有 2509 个。

您正在寻找的是一个powerset。这实际上可以通过 itertools 快速实现,您在 documentation 中有一个配方,我在这里根据您的需要进行了调整:

from itertools import chain, combinations

def powerset(iterable, maximum=6):
    s = list(iterable)
    if not maximum:
        maximum=len(s)
    return chain.from_iterable(combinations(s, r) for r in range(1, maximum+1))

然后使用:

chords = list(powerset(range(12), maximum=6))

...运行时间为 200µs,而不是 30 小时 ;)

如果您真的想要排列,请将上述代码中的combinations 替换为permutations。运行时间约为 100µs。

【讨论】:

  • 如果我理解正确的话,这样就没有重复的组合,每个组合也没有重复的注释,对吧?如果是这样,那就比我想象的还要好。
  • 是的,这就是无替换组合的定义;)
猜你喜欢
  • 2021-07-03
  • 1970-01-01
  • 2020-05-17
  • 2021-12-29
  • 2015-12-09
  • 1970-01-01
  • 2018-12-29
  • 2022-07-27
  • 1970-01-01
相关资源
最近更新 更多