Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何摆脱Python代码中的嵌套for循环?_Python_Loops_Numpy_For Loop_Parallel Processing - Fatal编程技术网

如何摆脱Python代码中的嵌套for循环?

如何摆脱Python代码中的嵌套for循环?,python,loops,numpy,for-loop,parallel-processing,Python,Loops,Numpy,For Loop,Parallel Processing,我有一年的电子卫星测量(仪器每4秒测量一次)。这个阵列被称为“电子”。我还有datetime.datetime格式的相应时间(称为“时间”)。我想对电子阵列求平均值,得到每分钟的平均值,而不是每4秒的平均值。我想把它们放在一个新的数组“g”中。然而,当我写循环时,它变得非常慢。有没有办法让它更快?以下是我的工作: import numpy as np import spacepy.time as spt import datetime as dt year=2001 for month in

我有一年的电子卫星测量(仪器每4秒测量一次)。这个阵列被称为“电子”。我还有datetime.datetime格式的相应时间(称为“时间”)。我想对电子阵列求平均值,得到每分钟的平均值,而不是每4秒的平均值。我想把它们放在一个新的数组“g”中。然而,当我写循环时,它变得非常慢。有没有办法让它更快?以下是我的工作:

import numpy as np
import spacepy.time as spt
import datetime as dt

year=2001
for month in range (1,13):
        dmax=np.array([[31,28,31,30,31,30,31,31,30,31,30,31]]).T #number of days in a month
        for day in range(1,dmax[month-1]+1):
            for hour in range(24):
                for minute in range(60):

                D1=spt.Ticktock(dt.datetime(year, month, day, hour, minute, 0,0),'UTC').RDT #lower boundary of a minute

#here, spt is a spacepy.time, and '.RDT' returns GREGORIAN ORDINAL TIME.

                D2=spt.Ticktock(dt.datetime(year, month, day, hour, minute, 59,999999),'UTC').RDT #upper boundary of a minute

                mask=((time>D1)&(time<D2))

                electrons_logic=electrons[mask]
                k=(month-1)*dmax[month-1]*24*60+(day-1)*24*60+hour*60+(minute+1) #number of the minute in a year
                g[k,0]=np.nanmean(electrons_logic)
将numpy导入为np
将spacepy.time导入为spt
将日期时间导入为dt
年份=2001年
对于范围(1,13)内的月份:
dmax=np.数组([[31,28,31,30,31,30,31,31,30,31]]).T#一个月内的天数
对于范围内的天(1,dmax[第1个月]+1):
范围内的小时数(24):
对于范围(60)内的分钟:
D1=标定点时间(dt.日期时间(年、月、日、小时、分钟,0,0),'UTC')。RDT#分钟的下限
#这里,spt是一个spacepy.time,“.RDT”返回格里高利顺序时间。
D2=标定点时间(dt.日期时间(年、月、日、小时、分钟,59999999),'UTC')。RDT#分钟的上限

掩码=((时间>D1)和(时间如果有任何静态初始化(针对代码)

它应该在for循环之外。因为每次循环运行时,该数组都会被初始化以进行大量计算。

替代方法(至少对于3个内部循环)是循环分钟数, 然后使用除法+余数计算小时和天:

dmax=np.array([[31,28,31,30,31,30,31,31,30,31,30,31]]).T #number of days in a month
for month in range (1,13):
    nb_days = dmax[month-1]
    for m in range(60*24*nb_days):
        hour,minute = divmod(m,60)
        day,hour = divmod(hour,nb_days)
        day += 1

这是在每次迭代中使用2个除法/模(使用
divmod
函数可以一次性完成)与2个循环之间的折衷。由于python循环非常昂贵,因此值得尝试。

每当您在迭代方面遇到问题时,请想一想


我还建议在循环之外定义
dmax
,否则它将在每个
迭代中实例化。

看起来除了计算秒之外,您没有使用月、日和分钟

您可以使用类似的方法在1个循环中完成,甚至不必硬编码一个月数组中的日期:

year=2001
DT1=dt.datetime(year, 1, 1, 0, 0, 0, 0),'UTC')
DT2=dt.datetime(year, 1, 1, 0, 0, 59, 999999),'UTC')
DToneSec=datetime.timedelta(seconds=1)
DTy=dt.datetime(year+1, 1, 1, 0, 0, 0, 0),'UTC')-DT1

for k in range (1,DTy.total_seconds()+1):
    D1=spt.Ticktock(DT1).RDT
    DT1+=DToneSec
    D2=spt.Ticktock(DT2).RDT
    DT2+=DToneSec

    g[k,0]=np.nanmean(electrons[(time>D1)&(time<D2)])
year=2001
DT1=dt.datetime(年份,1,1,0,0,0),'UTC')
DT2=dt.datetime(年份,1,1,0,0,599999),'UTC')
DToneSec=datetime.timedelta(秒=1)
DTy=dt.datetime(年份+1,1,1,0,0,0),'UTC')-DT1
对于范围内的k(1,DTy.总秒数()+1):
D1=标的滴答声(DT1).RDT
DT1+=DToneSec
D2=标的滴答声(DT2).RDT
DT2+=DToneSec

g[k,0]=np.nanmean(电子[(时间>D1)和(时间)你可以在分钟内循环(1个循环)使用divmod计算其他值。除法/模与循环折衷。值得计时。这可能很好!但是,问题是月份的天数不同,因此在某个点上进行除法将很困难…您仍然可以对3个内部循环进行除法。并在开始时定义
dmax
(并不是说要花太多时间,但还是…)pandas.resample maybe?itertools,总是itertools问题是itertools实际上比简单循环花费更多的时间。我计时了,简单循环速度快了13%。@TomSmith如果性能真的那么重要,你应该调整嵌套循环,因为它们肯定会更快。使用divmod by的解决方案可能会更快韩敏(我想是的,但没有测试),但它不会像循环那样快。事实上,使用divmod的解决方案会让它慢30%!我认为会有一些神奇的方法来改进它,但在我看来,我只需要等到它运行到最后……当需要性能时,采用原始的丑陋方式通常是解决方案,因为它们是调用但是如果从外部循环中删除dmax,那么您将获得显著的性能
from itertools import product

dmax=np.array([[31,28,31,30,31,30,31,31,30,31,30,31]]).T
for month in range (1,13):
    for day, hour, minute in product(range(1,dmax[month-1]+1), range(24), range(60)):
        ...
year=2001
DT1=dt.datetime(year, 1, 1, 0, 0, 0, 0),'UTC')
DT2=dt.datetime(year, 1, 1, 0, 0, 59, 999999),'UTC')
DToneSec=datetime.timedelta(seconds=1)
DTy=dt.datetime(year+1, 1, 1, 0, 0, 0, 0),'UTC')-DT1

for k in range (1,DTy.total_seconds()+1):
    D1=spt.Ticktock(DT1).RDT
    DT1+=DToneSec
    D2=spt.Ticktock(DT2).RDT
    DT2+=DToneSec

    g[k,0]=np.nanmean(electrons[(time>D1)&(time<D2)])