返回值时出现“NoneType”对象不可迭代的错误

3
我需要检查是否有任何簇只与一个点相关联,如果是,则需要计算所有簇中每个其他点的欧几里得距离,并将最小距离点添加到长度为1的簇(即具有关联点的簇)。之后,需要将点添加到簇的值的标签和中心进行更新。我已经完成了所有的事情,但有时当代码运行时,它会抛出错误“'NoneType' object is not iterable”,当它必须返回值时。我卡在这一部分,请帮忙,谢谢。以下是我的代码:
import numpy as np
import matplotlib.pyplot as mlt
import pandas as pd
from clustering import Kmeans_clu
import random
from collections import Counter, defaultdict
from math import sqrt
import matplotlib.pyplot as plt
import random



def ClusterIndicesComp(clustNum, labels_array):  # For extracting  points from the label
    return np.array([i for i, x in enumerate(labels_array) if x == clustNum])


def index(lst, obj, n):   # To find the index of of Lable which needs to be change
    count = 0
    for index, item in enumerate(lst):
        if item == obj:
            count += 1
        if count == n:
            return index
    raise ValueError('{} is not in list at least {} times'.format(obj, n))





def UpdateCentetr_Label(Index,lablelPlot1, plot2, lablePlot2, pop, plab, plot1, pcenter,cluster1,max_gen):

    s = list(plab) #Storing Value of Label in list
    print("Value of  in Label before\n", s)  # Before Updating the value of label
    s1 = Counter(s)
    print("Value of counter in before is \n", s1)
    Index=Index+1
    q = index(s, lablePlot2, Index)  #Storing the index of label which need to be changed
    s[q] = lablelPlot1          #Changing the label by labelPlot1
    ulabel = np.array(s)
    print("Value of an updated label is \n", ulabel)
    print("------------------------------------------")
    # print("Value of Pcenter in Updatedlabel\n",pcenter)
    ncenter = plot2 + plot1 / 2  #Calculating the center of label which have one point associated
    print("Value of new center to be updated\n", ncenter)
    ucenter = np.array(pcenter)
    #print("Value of ucenter is\n",ucenter)
    ucenter[lablelPlot1] = ncenter   #Changing the value of label with new center
    print("Value of updated center is\n", ucenter)
    ko = Counter(ulabel)
    print("Value of counter after updated label is\n", ko)
    LC1 = [t for (t, v) in ko.items() if v == 1]  # Again checking if there is label which have point associated
    t1 = np.array(LC1)
    if (t1.size):
        One_LengthCluster(cluster1, ulabel, ucenter, pop,max_gen) #To update the it again
    else:

        return ulabel,ucenter,cluster1






def ClusterPopulation(max_gen, population): # to cluster the population 


    pop = population
    plab1 = []
    pcenter = []
    u=[]
    cluster1 = int(input("Enter the cluster for new population\n"))
    plab=[]


    for i in range(0,max_gen):
        if (i % cluster1 == 1):      # Checking the condition of Kmeans Clustering
            u, label, t, l = Kmeans_clu(cluster1, population)   # Storing the values Center(u) anb label(u)
            plab1.insert(i, label)
            print("Plab is",plab)
            pcenter.insert(i, u)
            plab = np.array(plab1)
            plab=plab[0]
            #pcenter=np.array(pcenter)
            pcenter=pcenter[0]
            ulabel, ucenter, cluster1=One_LengthCluster(cluster1, plab, pcenter, pop,max_gen)   #To check if any label has one point associated
            return ulabel,ucenter,cluster1  #returning the value of ulabel, ucenter and cluster1
        else:
            print("Not need of clustering for this generation of\n", i)




def One_LengthCluster(cluster1, plab, pcenter, pop,max_gen):
    indexes = []
    Index=[]   #Store the index of Point which have minimum euclidean distance
    D=[] #Store the  minimum euclidean distance
    labelplot2=[] #Store the Label which have more than 2 points associated
    Point2=[]  #Store the Point which have minimum euclidean distance
    z=[]
    Smin=[]
    I=[]
    L=[]
    LC = Counter(plab)      #Counting number of points associated with label
    print("VAlue of LAbel and Number Cluster Associated with them\n", LC)
    LC1 = [t for (t, v) in LC.items() if v == 1]
    t1 = np.array(LC1)
    if (t1.size):# To check if any of the Label has one point associated if yes than calculate the distance with all the points 
        for b in range(len(t1)):
            plot1 = pop[ClusterIndicesComp(t1[b], plab)]  # Extracting the point in the label which have one point associated
            print("Point of label one Length PLOT1 is\n", np.array(plot1), t1[b])
            z1 = [t for (t, v) in LC.items() if v > 2]  # To check distance with label which more than 3 points associated
            z = np.array(z1)   #Storing the value in the array
            for d in range(len(z)):
                print("Value of Label which have more than two cluster is\n", z[d])
                plot2 = pop[ClusterIndicesComp(z[d], plab)] # Extracting the point in the label more than one point associated
                print("Value of plot2 in one length cluster is\n", plot2)
                for i in range(len(plot2)):
                    plotk = plot2[i]    # To get one point at a time from plot2
                    S = np.linalg.norm(np.array(plot1) - np.array(plotk))
                    print("Distance between {} and {} is {}\n".format(plot1,plotk,S))  # euclidian distance is calculated
                    if (i == 0):
                        Smin = S
                        Sminant = S
                        indexes.append(i)
                    else:
                        if (S < Sminant):
                            Smin = S
                            Sminant = Smin
                            indexes = []
                            indexes.append(i)
                        elif (S == Sminant):
                            indexes = []
                            indexes.append(i)

                #print('indexes:')
                print("Index at which the minimum value is stored\n", indexes)  # To find the index of Label with which euclidian distance is minimum

                for i in range(len(indexes)):
                    Point2 = plot2[indexes[i]]
                    I = indexes[i]
                    L = z[d]
                    print("VAlues of Point{} which have min distance with plot1 is in Label {} and have Index {} and distance {}\n".format(Point2,L,I,Smin))

                if(len(z)==1):  #If Label which have more than 2 point associated is only one
                    D = Smin
                    Index = indexes[i]
                    labelplot2=z[d]
                    Point2=plot2[indexes[i]]
                    print("Here is the value\n", D, Index, labelplot2, Point2)
                    ulabel, ucenter, cluster1=UpdateCentetr_Label(Index,t1[b], Point2, z[d], pop, plab, plot1, pcenter,cluster1,max_gen)  #After Finding Point now update center and label
                    return ulabel,ucenter,cluster1


                elif (len(z) > 1):  #If Label which have more than 2 point associated is more than one
                    D.append(Smin)
                    Index.append(I)
                    labelplot2.append(L)
                    #print("Value in list are------------\n", labelplot2)
                    print("Index value is\n",Index)
                    print("Label value is\n", labelplot2)

            z=min(D)    #Finding the minimum distance among all the labels
            k=D.index(z)  #Finding the index where minimum distance is stored in D
            Index=Index[k]
            labelplot2=labelplot2[k]
            Point2 = pop[ClusterIndicesComp(labelplot2, plab)]
            Point2=Point2[Index]
            print("Value of minimum distance is\n",z,Index,labelplot2,k,Point2)
            ulabel, ucenter, cluster1=UpdateCentetr_Label(Index,t1[b], Point2, labelplot2, pop, plab, plot1, pcenter,cluster1,max_gen)  #After Finding Point now update center and label
            return ulabel,ucenter,cluster1


        D=[]
        indexes=[]

    else:               #If no solution have one point associated in the label
        print("no lenght 1 cluster\n")
        return plab,pcenter,cluster1



population =np.random.rand(10,4) #Generating the random population 
max_gen=10 #Giving value of max_gen 
ulabel, ucenter, cluster1=ClusterPopulation(max_gen, population) #Taking back the values of ucenter ,ulabel and cluster1
print("Value of ulabel is\n",ulabel)

以下是我的 K-means 代码

from sklearn.cluster import KMeans
import numpy as np 

def Kmeans_clu(K, data):
    """
    :param K: Number of cluster
    :param data: 
    :return: 
    """
    kmeans = KMeans(n_clusters=K, init='random', max_iter=1, n_init=1).fit(data) ##Apply k-means clustering
    labels = kmeans.labels_
    clu_centres = kmeans.cluster_centers_
    z={i: np.where(kmeans.labels_ == i)[0] for i in range(kmeans.n_clusters)} #

    return clu_centres, labels ,z,kmeans

TraceBack is

Traceback (most recent call last):
  File "C:/Users/hp/AppData/Local/Programs/Python/Python36/Population Clustering.py", line 184, in <module>
    ulabel, ucenter, cluster1=ClusterPopulation(max_gen, population) #Taking back the values of ucenter ,ulabel and cluster1
  File "C:/Users/hp/AppData/Local/Programs/Python/Python36/Population Clustering.py", line 85, in ClusterPopulation
    ulabel, ucenter, cluster1=One_LengthCluster(cluster1, plab, pcenter, pop,max_gen)   #To check if any label has one point associated
  File "C:/Users/hp/AppData/Local/Programs/Python/Python36/Population Clustering.py", line 169, in One_LengthCluster
    ulabel, ucenter, cluster1=UpdateCentetr_Label(Index,t1[b], Point2, labelplot2, pop, plab, plot1, pcenter,cluster1,max_gen)  #After Finding Point now update center and label
  File "C:/Users/hp/AppData/Local/Programs/Python/Python36/Population Clustering.py", line 54, in UpdateCentetr_Label
    One_LengthCluster(cluster1, ulabel, ucenter, pop,max_gen) #To update the it again
  File "C:/Users/hp/AppData/Local/Programs/Python/Python36/Population Clustering.py", line 169, in One_LengthCluster
    ulabel, ucenter, cluster1=UpdateCentetr_Label(Index,t1[b], Point2, labelplot2, pop, plab, plot1, pcenter,cluster1,max_gen)  #After Finding Point now update center and label
TypeError: 'NoneType' object is not iterable

你能展示一下追踪信息吗? - Druta Ruslan
我已经展示了,请检查。 - Shivam Sharma
确保没有传递空值。这个错误通常出现在循环中。NoneType表示你正在传递的值中有一些数据是None,不能进行迭代。 - Sumit S Chawla
但是这个错误并非每次都会出现,只有很少的几次,所以如何检查空值? - Shivam Sharma
@ShivamSharma 你为什么把正确答案改成了 Dunjen.coder 的新帖子?他只是在几天后回复了完全相同的答案? - pansen
2个回答

4

我认为你在 UpdateCentetr_Label 函数中简单地漏掉了一个 return 语句,这会导致函数返回 None,而实际上它是不可迭代的:

def UpdateCentetr_Label(Index,lablelPlot1, plot2, lablePlot2, pop, plab, plot1, pcenter,cluster1,max_gen):

     # other code here...

     if (t1.size):
         return One_LengthCluster(cluster1, ulabel, ucenter, pop,max_gen) #To update the it again

1
你的函数中缺少简单的 return 语句。
def UpdateCentetr_Label(Index,lablelPlot1, plot2, lablePlot2, pop, plab, plot1, pcenter,cluster1,max_gen):

在检查t1的大小后,您只需要在One_length Cluster中添加返回即可

if (t1.size):
         return One_LengthCluster(cluster1, ulabel, ucenter, pop,max_gen) #To update the it again

1
@shivamsharma,我不是几天前已经给出了完全相同的答案吗?你们在这里干什么? - pansen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接