TypeError: can’t convert type ‘NoneType’ to numerator/denominator

Tags: , ,



Here I try to calculate mean value based on the data in two list of dicts. Although I used same code before, I keep getting error. Is there any solution?

import pandas as pd
data = pd.read_csv('data3.csv',sep=';') # Reading data from csv
data = data.dropna(axis=0) # Drop rows with null values
data = data.T.to_dict().values() # Converting dataframe into list of dictionaries
newdata = pd.read_csv('newdata.csv',sep=';') # Reading data from csv
newdata = newdata.T.to_dict().values() # Converting dataframe into list of dictionaries

score = []
for item in newdata:
  score.append({item['Genre_Name']:item['Ranking']})


from statistics import mean
score={k:int(v) for i in score for k,v in i.items()}  

for item in data:
  y= mean(map(score.get,map(str.strip,item['Recommended_Genres'].split(','))))

print(y)

Too see csv files: https://repl.it/@rmakakgn/SVE2

Answer

.get method of dict return None if given key does not exist and statistics.mean fail due to that, consider that

import statistics
d = {"a":1,"c":3}
data = [d.get(x) for x in ("a","b","c")]
print(statistics.mean(data))

result in:

TypeError: can't convert type 'NoneType' to numerator/denominator

You need to remove Nones before feeding into statistics.mean, which you can do using list comprehension:

import statistics
d = {"a":1,"c":3}
data = [d.get(x) for x in ("a","b","c")]
data = [i for i in data if i is not None]
print(statistics.mean(data))

or filter:

import statistics
d = {"a":1,"c":3}
data = [d.get(x) for x in ("a","b","c")]
data = filter(lambda x:x is not None,data)
print(statistics.mean(data))

(both snippets above code will print 2)

In this particular case, you might get filter effect by replacing:

mean(map(score.get,map(str.strip,item['Recommended_Genres'].split(','))))

with:

mean([i for i in map(score.get,map(str.strip,item['Recommended_Genres'].split(','))) if i is not None])

though as with most python built-in and standard library functions accepting list as sole argument, you might decide to not build list but feed created generator directly i.e.

mean(i for i in map(score.get,map(str.strip,item['Recommended_Genres'].split(','))) if i is not None)

For further discussion see PEP 202 xor PEP 289.



Source: stackoverflow