[英]How can I improve this nested for loop?
我想以另一種方式重寫函數get_bs,如何以更緊湊的方式改進此嵌套的for循環? 有什么建議么?
我當時在想,可以將嵌套循環分為兩個不同的嵌套循環,每個循環寫在一行中,例如對於i,j in ....這可能嗎? 有人可以告訴我嗎? 謝謝。
class NB:
def __init__(self, train_data, test_data):
self.train_data = train_data
self.test_data = test_data
self.train_entries = []
self.test_entries = []
self.diabetes_yes = []
self.diabetes_no = []
self.a_diabetesyes = []
self.a_diabetesno = []
self.b_diabetesyes = []
self.b_diabetesno = []
self.num_elements = 0
self.p_diabetesyes = 0
self.p_diabetesno = 0
self.num_diabetesyes = 0
self.num_diabetesno = 0
def trainNB(self):
self.traincleandata()
for i in range(self.num_elements - 1):
self.a_diabetesyes[i] = sum(self.diabetes_yes[i]) / len(self.diabetes_yes[i])
self.a_diabetesno[i] = sum(self.diabetes_no[i]) / len(self.diabetes_no[i])
self.get_bs()
def traincleandata(self):
for line in self.train_data:
if self.num_elements == 0:
self.num_elements = len(line.split(','))
for i in range(self.num_elements):
self.diabetes_yes.append([])
self.diabetes_no.append([])
self.a_diabetesyes.append(0.0)
self.a_diabetesno.append(0.0)
self.b_diabetesyes.append(0.0)
self.b_diabetesno.append(0.0)
params = line.split(',')
cleanparams = getcleanparams(params)
entry = Entry(cleanparams)
self.train_entries.append(entry)
for i in range(len(entry.elements) - 1):
if (entry.diabetes == "yes"):
self.diabetes_yes[i].append(Decimal(entry.elements[i]))
else:
self.diabetes_no[i].append(Decimal(entry.elements[i]))
if (entry.diabetes == 'yes'):
self.p_diabetesyes += 1
self.num_diabetesyes += 1
else:
self.p_diabetesno += 1
self.num_diabetesno += 1
self.p_diabetesyes = Decimal(self.p_diabetesyes) / Decimal(len(self.train_entries))
self.p_diabetesno = Decimal(self.p_diabetesno) / Decimal(len(self.train_entries))
def get_bs(self):
sigSumYes = [0] * self.num_elements
sigSumNo = [0] * self.num_elements
for i in range(self.num_elements - 1):
for j in range(self.num_diabetesyes):
diff_yes = self.diabetes_yes[i][j] - self.a_diabetesyes[i]
sigSumYes[i] += m.pow(diff_yes, 2)
self.b_diabetesyes[i] = m.sqrt(sigSumYes[i] / (len(self.diabetes_yes[i]) - 1))
for j in range(self.num_diabetesno):
diff_no = self.diabetes_no[i][j] - self.a_diabetesno[i]
sigSumNo[i] += m.pow(diff_no, 2)
self.b_diabetesno[i] = m.sqrt(sigSumNo[i] / (len(self.diabetes_no[i]) - 1))
def testNB(self):
self.testcleandata()
self.testalgo()
def testcleandata(self):
for line in self.test_data:
params = line.split(',')
cleanparams = getcleanparams(params)
entry = Entry(cleanparams)
self.test_entries.append(entry)
def testalgo(self):
counter = 1
P_diabetesyes = [0] * self.num_elements
P_diabetesno = [0] * self.num_elements
for entry in self.test_entries:
pYesEntry = 1
pNoEntry = 1
pYesEntry, pNoEntry = self.test_Entry(pYesEntry, pNoEntry, P_diabetesyes, P_diabetesno, entry)
pYesEntry *= float(self.p_diabetesyes)
pNoEntry *= float(self.p_diabetesno)
entry.set_ifdiabetes("yes") if (pYesEntry / pNoEntry >= 1) else entry.set_ifdiabetes("no")
counter += 1
def test_Entry(self, pYesEntry, pNoEntry, P_diabetesyes, P_diabetesno, entry):
for i in range(self.num_elements - 1):
P_diabetesyes[i] = Decimal((1 / (self.b_diabetesyes[i] * m.sqrt(2 * m.pi))) * m.pow(m.e, (
-m.pow(Decimal(entry.elements[i]) - self.a_diabetesyes[i], 2) / (
2 * m.pow(self.b_diabetesyes[i], 2)))))
P_diabetesno[i] = Decimal((1 / (self.b_diabetesno[i] * m.sqrt(2 * m.pi))) * m.pow(m.e, (
-m.pow(Decimal(entry.elements[i]) - self.a_diabetesno[i], 2) / (
2 * m.pow(self.b_diabetesno[i], 2)))))
pYesEntry *= float(P_diabetesyes[i])
pNoEntry *= float(P_diabetesno[i])
return pYesEntry, pNoEntry
由於您在評論中問我如何執行此操作...
使用itertools在單行代碼中獲得嵌套循環的i,j索引:
import itertools
for i, j in itertools.product(range(self.num_elements - 1),
range(self.num_diabetesyes)):
diff_yes = self.diabetes_yes[i][j] - self.a_diabetesyes[i]
sigSumYes[i] += m.pow(diff_yes, 2)
diff_no = self.diabetes_no[i][j] - self.a_diabetesno[i]
sigSumNo[i] += m.pow(diff_no, 2)
之后,為僅迭代i的部分設置單獨的for循環。
for i in range(self.num_elements - 1):
self.b_diabetesyes[i] = m.sqrt(sigSumYes[i] / (len(self.diabetes_yes[i]) - 1))
self.b_diabetesno[i] = m.sqrt(sigSumNo[i] / (len(self.diabetes_no[i]) - 1))
請注意,我認為這不是最好的方法。 使用Numpy和向量數學將更快,更優雅。
通常,“無庫”規則指的是“不要使用要求您實現的算法的現成實現”。 不是“不要使用任何外部便利類”。
也許沒有人敢回答您在更改代碼時不應該總是走得更遠,尤其是在代碼工作時。 最重要的軟件通常由於重復而難以編輯。 只需改善功能或切換到新軟件即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.