循环通过大型numpy数组的有效方法

时间:2016-11-10 20:08:41

标签: python numpy scipy scikit-learn

我正致力于构建一个模糊的推理系统,我需要找到一种方法来加速我的代码:

import skfuzzy as fuzz
from skfuzzy import control as ctrl
import numpy as np


def FIS(s, r):
    #Generate universe variables
    a = ctrl.Antecedent(np.arange(0, 70.1, 0.1), 'a')
    b = ctrl.Antecedent(np.arange(0, 6.01, 0.01), 'b')
    c = ctrl.Consequent(np.arange(0, 12.01, 0.01), 'c')

    #Generate fuzzy membership functions
    #a
    a['l'] = fuzz.trapmf(a.universe, [0.0, 0.0, 3.0, 6.0])
    a['m'] = fuzz.trapmf(a.universe,[3.0, 6.0, 16.0, 24.0])
    a['h'] = fuzz.trapmf(a.universe, [16.0, 24.0, 30.0, 45.0])
    a['e'] = fuzz.trapmf(a.universe, [30.0, 45.0, 70.0, 70.0])

    #b
    b['l'] = fuzz.trapmf(b.universe, [0, 0, 0.01, 0.02])
    b['m'] = fuzz.trapmf(b.universe,[0.01, 0.02, 0.03, 0.05])
    b['h'] = fuzz.trapmf(b.universe, [0.03, 0.05, 0.10, 0.12])
    b['e'] = fuzz.trapmf(b.universe, [0.10, 0.12, 6.00, 6.00])

    #c
    c['l'] = fuzz.trapmf(c.universe, [0, 0, 0.01, 0.02])
    c['m'] = fuzz.trapmf(c.universe,[0.01, 0.02, 0.04, 0.05])
    c['h'] = fuzz.trapmf(c.universe, [0.04, 0.05, 0.10, 0.20])
    c['e'] = fuzz.trapmf(c.universe, [0.10, 0.20, 12.00, 12.00])

    #FUZZY RULES
    rule1 = ctrl.Rule(a['l'] & b['l'], c['l'])
    rule2 = ctrl.Rule(a['l'] & b['m'], c['m'])
    rule3 = ctrl.Rule(a['l'] & b['h'], c['h'])
    rule4 = ctrl.Rule(a['m'] & b['l'], c['m'])
    rule5 = ctrl.Rule(a['m'] & b['m'], c['m'])
    rule6 = ctrl.Rule(a['m'] & b['h'], c['h'])
    rule7 = ctrl.Rule(a['h'] & b['l'], c['h'])
    rule8 = ctrl.Rule(a['h'] & b['m'], c['h'])
    rule9 = ctrl.Rule(a['h'] & b['h'], c['e'])
    rule10 = ctrl.Rule(a['e'], c['e'])
    rule11 = ctrl.Rule(b['e'], c['e'])

    #CONTROL SYSTEM
    c_ctrl = ctrl.ControlSystem([rule1, rule2, rule3, rule4, rule5, rule6,
    rule7, rule8, rule9, rule10, rule11])
    c_simulation = ctrl.ControlSystemSimulation(c_ctrl)

    c_simulation.input['a'] = s
    c_simulation.input['b'] = r

    c_simulation.compute()

    value = c_simulation.output['c']

    return value

#Fake data
s_data = np.random.RandomState(1234567890)
s_data = s_data.randint(0, 70, size=600000)

r_data = np.random.random_sample(600000)

vec1 = s_data.flatten().astype('float')
vec2 = r_data.flatten().astype('float')

#pre allocate output array
cert = np.zeros(np.shape(vec1))*np.nan

#Find index of all finite elements of the array
ind = np.where(np.isfinite(vec1))[0]

# classify 
for k in xrange(len(ind)):
   cert[ind[k]] = FIS(vec1[ind[k]], vec2[ind[k]])

我的计算完成时间超过10个小时。如何在没有for循环的情况下执行这些计算?理想情况下,我会寻找numpy解决方案,但我愿意接受其他解决方案。

1 个答案:

答案 0 :(得分:1)

我想赞扬来自scikit-fuzzy google小组的JDWarner对上述问题的出色答案。我认为其他scikit-fuzzy用户会发现此帖子在将来有用。

https://groups.google.com/forum/#!topic/scikit-fuzzy/AOO0iNuHEuo