title: unhashable type: 'numpy.ndarray' python
body: <p>I am completing a codeusing the bayesian classifier using the gaussian distribution.
  In some part of the code as you can see I need to define a dictionary called meanDict for calculating the mean of parameters X1 and X2 and then use the same calculateMeanDict function to calulate the var in the calculate var function.
  However, after getting to the <code>var = np.mean((X-meanDict[y])^2)</code> part of the code, I receive a <strong>TypeError: unhashable type: 'numpy.ndarray' error.</strong>
  Can anybody please help me on this?</p>
  <pre><code># !!! Must Not Change the Imports !!!
  from pathlib import Path
  from typing import Dict
  
  import numpy as np
  import pandas as pd
  from sklearn.metrics import classification_report
  from sklearn.model_selection import train_test_split
  from sklearn.preprocessing import LabelEncoder, MinMaxScaler
  
  from TicToc import timing, Timer
  
  
  def loadDataset(filepath='Data/PokemonUnivariate.csv', labelCol='type1') -&gt; (np.ndarray, np.ndarray, LabelEncoder):
      &quot;&quot;&quot;
      !!! Must Not Change the Content !!!
      This function is used to load dataset
      Data will be scaled from 0 to 1
      :param filepath: csv file path
      :param labelCol: column name
      :return: X: ndarray, y: ndarray, labelEncoder
      &quot;&quot;&quot;
      data = pd.read_csv(filepath)
      y = data[labelCol].values
      labelEncoder = LabelEncoder()
      y = labelEncoder.fit_transform(y)
      X = data.drop(columns=[labelCol]).values
      X = np.nan_to_num(X)
      scaler = MinMaxScaler()
      X = scaler.fit_transform(X)
      return X, y, labelEncoder
  
  
  class LinearClassifier(object):
      def __init__(self):
          &quot;&quot;&quot;!!! Must Not Change the Content !!!&quot;&quot;&quot;
          self.X = None
          self.y = None
          self.w = 0
          self.b = 0
  
      def name(self) -&gt; str:
          &quot;&quot;&quot;!!! Must Not Change the Content !!!&quot;&quot;&quot;
          return self.__class__.__name__
  
      def sigmoid(self, X, w=None, b=None):
          &quot;&quot;&quot;
          !!! Must Not Change the Content !!!
          Sigmoid function
          :param X: X
          :param w: weight
          :param b: bias
          :return: sigmoid(wx + b)
          &quot;&quot;&quot;
          w, b = self.w if w is None else w, self.b if b is None else b
          return 1 / (1 + np.exp(-(w * X + b)))
  
      def fit(self, X, y):
          &quot;&quot;&quot;!!! Must Not Change the Content !!!&quot;&quot;&quot;
          raise NotImplementedError
  
      def predictSample(self, x) -&gt; int:
          &quot;&quot;&quot;
          ToDo: Implement This Function
          Predict a label of given x
          If sigmoid(x) is greater than 0.5, then the label is 1; otherwise the label is 0
          :param x: a sample
          :return: a label
          &quot;&quot;&quot;
          if sigmoid(X, w, b) &gt; 0.5:
              label = 1
          else:
              label = 0
          return label
  
      def predict(self, X):
          &quot;&quot;&quot;
          !!! Must Not Change the Content !!!
          Predict the labels of given X
          If sigmoid(x) is greater than 0.5, then the label is 1; otherwise the label is 0
          &quot;&quot;&quot;
          return np.apply_along_axis(self.predictSample, axis=1, arr=X)
  
  
  class UnivariateGaussianDiscriminantAnalysisClassifier(LinearClassifier):
      &quot;&quot;&quot;
      Univariate Gaussian Classifier
      Univariate &amp; Binary Class
      &quot;&quot;&quot;
      @staticmethod
      def lnPrior(X1, X2):
          &quot;&quot;&quot;
          !!! Must Not Change the Content !!!
          Calculate the ln P(C1) and ln P(C2)
          :param X1: X with C1 label
          :param X2: X with C2 label
          :return (ln P(C1), ln P(C2))
          &quot;&quot;&quot;
          (nX1, _), (nX2, _) = X1.shape, X2.shape
          return np.log(nX1 / (nX1 + nX2)), np.log(nX2 / (nX1 + nX2))
  
      @staticmethod
      def calculateMeanDict(X1, X2) -&gt; Dict[int, float]:
          &quot;&quot;&quot;
          ToDo: Implement This Function
          This function should return a diction,
          which 0: mean X1, and 1: mean X2
          :param X1: ndarray
          :param X2: ndarray
          :return: mean dict
          &quot;&quot;&quot;
          meanDict = dict(mean_X1= np.mean(X1), mean_X2= np.mean(X2))
          return meanDict
  
      @staticmethod
      def calculateVar(meanDict, X, y) -&gt; float:
          &quot;&quot;&quot;
          ToDo: Implement This Function
          This function calculates the variance of X
          var = mean (xi-meanDict[yi])^2
          :param meanDict: 0: mean X1, and 1: mean X2
          :param X: X
          :param y: y
          :return: var
          &quot;&quot;&quot;
          var = meanDict['mean_X1']
          #var = np.mean((X-meanDict[y])^2)
          return var
  
      @staticmethod
      def calculateW(meanDict, var) -&gt; float:
          &quot;&quot;&quot;
          ToDo: Implement This Function
          Calculate w. w=(mean2-mean1)/var
          :param meanDict: 0: mean X1, and 1: mean X2
          :param var: variance
          :return: w
          &quot;&quot;&quot;
          w = (meanDict['mean_X1'] - meanDict['mean_X2'])/var^2
          return w
  
      @staticmethod
      def calculateB(meanDict, var, lnPrior1, lnPrior2) -&gt; float:
          &quot;&quot;&quot;
          ToDo: Implement This Function
          calculate b. b=(mean1^2-mean2^2)/(2*var) + ln(P(C2)) - ln(P(C1))
          :param meanDict: 0: mean X1, and 1: mean X2
          :param var: variance
          :param lnPrior1: ln(P(C1))
          :param lnPrior2: ln(P(C2))
          :return: b
          &quot;&quot;&quot;
          b = ((meanDict['mean X1'])^2 -(meanDict['mean X2'])^2/(2*var^2)) + lnPrior2 - lnPrior1
  
      def fit(self, X, y):
          &quot;&quot;&quot;
          !!! Must Not Change the Content !!!
          Train the Univariate Gaussian Classifier
          :param X: shape (N Samples, 1)
          :param y: shape (1, N Samples)
          &quot;&quot;&quot;
          self.X, self.y = X, y
          nX, _ = X.shape
          X1 = np.array([x1 for x1, y1 in zip(X, y) if y1 == 0])
          X2 = np.array([x2 for x2, y2 in zip(X, y) if y2 == 1])
          lnPrior1, lnPrior2 = self.lnPrior(X1, X2)
          meanDict = self.calculateMeanDict(X1, X2)
          var = self.calculateVar(meanDict, X, y)
          self.w = self.calculateW(meanDict, var)
          self.b = self.calculateB(meanDict, var, lnPrior1, lnPrior2)
          return self
  
  
  @timing
  def main():
      &quot;&quot;&quot;
      !!! Must Not Change the Content !!!
      &quot;&quot;&quot;
      randomState = 0
      resultFolder = Path('Data/')
  
      with Timer('Data Loaded'):
          X, y, _ = loadDataset()
          XTrain, XTest, yTrain, yTest = \
              train_test_split(X, y, test_size=0.2, random_state=randomState)
          print(f'Training Set Length: {XTrain.shape[0]}\n'
                f'Testing Set Length: {XTest.shape[0]}')
      classifiers = [UnivariateGaussianDiscriminantAnalysisClassifier()]
      for classifier in classifiers:
          with Timer(f'{classifier.name()} Trained'):
              classifier.fit(XTrain, yTrain)
          with Timer(f'{classifier.name()} Tested'):
              yPredicted = classifier.predict(XTest)
          with Timer(f'{classifier.name()} Results Saved'):
              resultsCsv = pd.DataFrame()
              resultsCsv['yPredicted'] = yPredicted
              resultsCsv['yTrue'] = yTest
              resultsCsvPath = resultFolder / f'{classifier.name()}Results.csv'
              resultsCsv.to_csv(resultsCsvPath, index=False)
  
              resultsStr = f'{classification_report(yTest, yPredicted, digits=5)}\n' \
                           f'{classifier.name()}: w={classifier.w}; b={classifier.b}'
              resultsTxtPath = resultFolder / f'{classifier.name()}Results.txt'
              with open(resultsTxtPath, 'w') as resultsTxtFile:
                  resultsTxtFile.write(resultsStr)
              print(resultsStr)
  
  
  if __name__ == '__main__':
      main(timerPrefix='Total Time Costs: ', timerBeep=False)
  
  
  </code></pre>