python如何提高熵权法的算法效率
how to improve algorithm efficiency of entropy weight method in python
下面是代码,但是,处理大数据时速度很慢。 (5,000,000 行,6 列 数据框可能需要 >1 天。
只是想知道我该如何优化它?非常感谢
def ewm(df):
df = df.apply(lambda x: ((x - np.min(x)) / (np.max(x) - np.min(x))))
rows, cols = df.shape
k = 1.0 / math.log(rows)
lnf = [[None] * cols for i in range(rows)]
for i in range(0, rows):
for j in range(0, cols):
if df.iloc[i][j] == 0:
lnfij = 0.0
else:
p = df.iloc[i][j] / df.iloc[:,j].sum()
lnfij = math.log(p) * p * (-k)
lnf[i][j] = lnfij
lnf = pd.DataFrame(lnf)
d = 1 - lnf.sum(axis=0)
w = [[None] * 1 for i in range(cols)]
for j in range(0, cols):
wj = d[j] / sum(d)
w[j] = wj
w = pd.DataFrame(w)
w = w.round(5) #.applymap(lambda x:format(x,'.5f'))
w.index = df.columns
w.columns =['weight']
return w
获取特定值时使用 iat 而不是 iloc
如果你做同样的 iloc 两次,将它保存在 tmp
import pandas as pd
import time
import numpy as np
import math
#original method
def ewm(df):
df = df.apply(lambda x: ((x - np.min(x)) / (np.max(x) - np.min(x))))
rows, cols = df.shape
k = 1.0 / math.log(rows)
lnf = [[None] * cols for i in range(rows)]
for i in range(0, rows):
for j in range(0, cols):
if df.iloc[i][j] == 0:
lnfij = 0.0
else:
p = df.iloc[i][j] / df.iloc[:,j].sum()
lnfij = math.log(p) * p * (-k)
lnf[i][j] = lnfij
lnf = pd.DataFrame(lnf)
d = 1 - lnf.sum(axis=0)
w = [[None] * 1 for i in range(cols)]
for j in range(0, cols):
wj = d[j] / sum(d)
w[j] = wj
w = pd.DataFrame(w)
w = w.round(5) #.applymap(lambda x:format(x,'.5f'))
w.index = df.columns
w.columns =['weight']
return w
#modified method
def ewm1(df):
df = df.apply(lambda x: ((x - np.min(x)) / (np.max(x) - np.min(x))))
rows, cols = df.shape
k = 1.0 / math.log(rows)
lnf = [[None] * cols for i in range(rows)]
for i in range(0, rows):
for j in range(0, cols):
tmp = df.iat[i,j] #********************************* modified section
if tmp == 0:
lnfij = 0.0
else:
p = tmp / df.iloc[:,j].sum() #************************ end of modified
lnfij = math.log(p) * p * (-k)
lnf[i][j] = lnfij
lnf = pd.DataFrame(lnf)
d = 1 - lnf.sum(axis=0)
w = [[None] * 1 for i in range(cols)]
for j in range(0, cols):
wj = d[j] / sum(d)
w[j] = wj
w = pd.DataFrame(w)
w = w.round(5) #.applymap(lambda x:format(x,'.5f'))
w.index = df.columns
w.columns =['weight']
return w
df = pd.DataFrame(np.random.rand(1000,6))
start = time.time()
ewm(df)
print(time.time()-start)
start1 = time.time()
ewm1(df)
print(time.time()-start1)
第一个函数的时间是 1.9747240543365479
第二个是 0.820796012878418
我不确定该方法的作用
但是如果你可以将它分解成几个具有数字 return 值的函数
你可以散列它们并进一步改进它
让 numpy 执行循环应该会加快很多速度
import numpy as np
import pandas as pd
def ewm(df):
df = df.apply(lambda x: ((x - np.min(x)) / (np.max(x) - np.min(x))))
rows, cols = df.shape
k = 1.0 / math.log(rows)
p = df / df.sum(axis=0)
lnf = -np.log(p , where = df!=0 )*p*k
d = 1 - lnf.sum(axis=0)
w = d / d.sum()
w = pd.DataFrame(w)
w = w.round(5)
w.index = df.columns
w.columns =['weight']
return w
下面是代码,但是,处理大数据时速度很慢。 (5,000,000 行,6 列 数据框可能需要 >1 天。
只是想知道我该如何优化它?非常感谢
def ewm(df):
df = df.apply(lambda x: ((x - np.min(x)) / (np.max(x) - np.min(x))))
rows, cols = df.shape
k = 1.0 / math.log(rows)
lnf = [[None] * cols for i in range(rows)]
for i in range(0, rows):
for j in range(0, cols):
if df.iloc[i][j] == 0:
lnfij = 0.0
else:
p = df.iloc[i][j] / df.iloc[:,j].sum()
lnfij = math.log(p) * p * (-k)
lnf[i][j] = lnfij
lnf = pd.DataFrame(lnf)
d = 1 - lnf.sum(axis=0)
w = [[None] * 1 for i in range(cols)]
for j in range(0, cols):
wj = d[j] / sum(d)
w[j] = wj
w = pd.DataFrame(w)
w = w.round(5) #.applymap(lambda x:format(x,'.5f'))
w.index = df.columns
w.columns =['weight']
return w
获取特定值时使用 iat 而不是 iloc 如果你做同样的 iloc 两次,将它保存在 tmp
import pandas as pd
import time
import numpy as np
import math
#original method
def ewm(df):
df = df.apply(lambda x: ((x - np.min(x)) / (np.max(x) - np.min(x))))
rows, cols = df.shape
k = 1.0 / math.log(rows)
lnf = [[None] * cols for i in range(rows)]
for i in range(0, rows):
for j in range(0, cols):
if df.iloc[i][j] == 0:
lnfij = 0.0
else:
p = df.iloc[i][j] / df.iloc[:,j].sum()
lnfij = math.log(p) * p * (-k)
lnf[i][j] = lnfij
lnf = pd.DataFrame(lnf)
d = 1 - lnf.sum(axis=0)
w = [[None] * 1 for i in range(cols)]
for j in range(0, cols):
wj = d[j] / sum(d)
w[j] = wj
w = pd.DataFrame(w)
w = w.round(5) #.applymap(lambda x:format(x,'.5f'))
w.index = df.columns
w.columns =['weight']
return w
#modified method
def ewm1(df):
df = df.apply(lambda x: ((x - np.min(x)) / (np.max(x) - np.min(x))))
rows, cols = df.shape
k = 1.0 / math.log(rows)
lnf = [[None] * cols for i in range(rows)]
for i in range(0, rows):
for j in range(0, cols):
tmp = df.iat[i,j] #********************************* modified section
if tmp == 0:
lnfij = 0.0
else:
p = tmp / df.iloc[:,j].sum() #************************ end of modified
lnfij = math.log(p) * p * (-k)
lnf[i][j] = lnfij
lnf = pd.DataFrame(lnf)
d = 1 - lnf.sum(axis=0)
w = [[None] * 1 for i in range(cols)]
for j in range(0, cols):
wj = d[j] / sum(d)
w[j] = wj
w = pd.DataFrame(w)
w = w.round(5) #.applymap(lambda x:format(x,'.5f'))
w.index = df.columns
w.columns =['weight']
return w
df = pd.DataFrame(np.random.rand(1000,6))
start = time.time()
ewm(df)
print(time.time()-start)
start1 = time.time()
ewm1(df)
print(time.time()-start1)
第一个函数的时间是 1.9747240543365479
第二个是 0.820796012878418
我不确定该方法的作用 但是如果你可以将它分解成几个具有数字 return 值的函数 你可以散列它们并进一步改进它
让 numpy 执行循环应该会加快很多速度
import numpy as np
import pandas as pd
def ewm(df):
df = df.apply(lambda x: ((x - np.min(x)) / (np.max(x) - np.min(x))))
rows, cols = df.shape
k = 1.0 / math.log(rows)
p = df / df.sum(axis=0)
lnf = -np.log(p , where = df!=0 )*p*k
d = 1 - lnf.sum(axis=0)
w = d / d.sum()
w = pd.DataFrame(w)
w = w.round(5)
w.index = df.columns
w.columns =['weight']
return w