Здесь:
lines = csv.reader(csvfile)
Вы должны указать csv.reader , какой разделитель использовать , иначе он будет использовать разделитель по умолчанию Excel ','.Обратите внимание, что в примере, который вы разместили, разделитель на самом деле НЕ может быть «пробелом», но может быть либо табуляцией ("\t"
в python), либо просто случайным числом пробелов - в этом случае это не csv-подобный формат, и выПридется разбирать строки самостоятельно.
Также ваш код далеко не пифоновский.Перво-наперво: цикл for for for действительно предназначен для каждого вида циклов, то есть они напрямую выдают значения из объекта, с которым вы итерируете.Правильный способ итерации по списку:
lst = ["a", "b", "c"]
for item in lst:
print(item)
, поэтому нет необходимости в range()
и индексированном доступе здесь.Обратите внимание, что если вы хотите иметь индекс тоже, вы можете использовать enumerate(sequence)
, что даст (index, item)
пар, то есть:
lst = ["a", "b", "c"]
for index, item in enumerate(lst):
print("item at {} is {}".format(index, item))
Так что ваша функция loadDataset () может быть переписана как:
def loadDataset(filename, split, trainingSet=None , testSet=None):
# fix the mutable default argument gotcha
# cf https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments
if trainingSet is None:
trainingSet = []
if testSet is None:
testSet = []
with open(filename, 'rb') as csvfile:
reader = csv.reader(csvfile, delimiter="\t")
for row in reader:
row = tuple(float(x) for x in row)
if random.random() < split:
trainingSet.append(row)
else:
testSet.append(row)
# so the caller can get the values back
return trainingSet, testSet
Обратите внимание, что если какое-либо значение в вашем файле не является правильным представлением с плавающей точкой, вы все равно получите ValueError
в row = tuple(float(x) for x in row)
.Решение здесь состоит в том, чтобы перехватить ошибку и обработать ее тем или иным способом - либо путем ее повторного вызова с дополнительной отладочной информацией (какое значение является неправильным и какой строке файла она принадлежит), либо путем регистрации ошибки и игнорирования этой строки илиэто имеет смысл в контексте вашего приложения / lib:
for row in reader:
try:
row = tuple(float(x) for x in row)
except ValueError as e:
# here we choose to just log the error
# and ignore the row, but you may want
# to do otherwise, your choice...
print("wrong value in line {}: {}".format(reader.line_num, row))
continue
if random.random() < split:
trainingSet.append(row)
else:
testSet.append(row)
Кроме того, если вы хотите выполнить итерацию по двум спискам параллельно (получите пары 'list1 [x], list2 [x]'), вы можете использовать zip()
:
lst1 = ["a", "b", "c"]
lst2 = ["x", "y", "z"]
for pair in zip(lst1, lst2):
print(pair)
и есть функции для sum()
значений из итерируемого, то есть:
lst = [1, 2, 3] print (sum (lst))
, поэтому ваша euclideanDistance
функция может быть переписана как:
def euclideanDistance(instance1, instance2, length):
pairs = zip(instance1[:length], instance2[:length])
return math.sqrt(sum(pow(x - y) for x, y in pairs))
и т. д. и т. д. *