Can Anyone Explain this code piece by piece?
def pd_centers(**featuresUsed**, centers):


inputs of the function are featuresUsed that are the features(column names) you already have and centers.

colNames = list(**featuresUsed**) 


names of columns (featuresUsed) are saved here as a list named colNames

colNames.append('prediction')


Here a new column name rather than those already existing is added to column names (features) named prediction

# Zip with a column called 'prediction' (index)
Z = [np.append(A, index) for index, A in enumerate(centers)]


A list of elements of centers with their indices are saved as Z
For instance, if we have centers equal to ['CA', 'TEX', 'FLO', 'ORE']
 then Z would become and finally these indices would become the values of prediction column.

[array(['CA', '0'], dtype='&lt;U21'),
 array(['TEX', '1'], dtype='&lt;U21'),
 array(['FLO', '2'], dtype='&lt;U21'),
 array(['ORE', '3'], dtype='&lt;U21')]


# Convert to a pandas data frame for plotting
P = pd.DataFrame(Z, columns=colNames) #save Z as a dataframe with columns colNames
P['prediction'] = P['prediction'].astype(int) #converting the values in Prediction column to int type
return P


here Z is converted to dataframe named P and the elements in the prediction column is converted to int type and P as the ultimate dataframe is returned. this prediction column is the cluster number.

if centers is a list of tuples, and it should be I assume, then instead of increasing indices, then the corresponding elements in each tuple are saved as A and index.