def averager(filename):
f=open(filename, "r")
avg=f.readlines()
f.close()
avgr=[]
final=""
x=0
i=0
while i < range(len(avg[0])):
while x < range(len(avg)):
avgr+=str((avg[x[i]]))
x+=1
final+=str((sum(avgr)/(len(avgr))))
clear(avgr)
i+=1
return final
我得到的错误是:
File "C:\Users\konrad\Desktop\exp\trail3.py", line 11, in averager
avgr+=str((avg[x[i]]))
TypeError: 'int' object has no attribute '__getitem__'
答案 0 :(得分:2)
x
只是一个整数,因此您无法将其编入索引。
所以,这个:
x[i]
永远不应该工作。这就是错误所抱怨的。
<强>更新强>
由于您要求提供有关如何简化代码的建议(在下面的评论中),所以请点击:
假设您的CSV文件类似于:
-9,2,12,90...
1423,1,51,-12...
...
您可以像这样阅读文件:
with open(<filename>, 'r') as file_reader:
file_lines = file_reader.read().split('\n')
请注意,我使用了.split('\n')
。这会导致文件的内容存储在file_lines
中,因为它是文件中的行列表。
因此,假设您想要对i
列进行求和,可以通过理解轻松完成:
ith_col_sum = sum(float(line.split(',')[i]) for line in file_lines if line)
那么为了平均一切,你可以将总和除以行数:
average = ith_col_sum / len(file_lines)
答案 1 :(得分:1)
其他人指出了错误的根本原因。以下是编写方法的不同方法:
def csv_average(filename, column):
""" Returns the average of the values in
column for the csv file """
column_values = []
with open(filename) as f:
reader = csv.reader(f)
for row in reader:
column_values.append(row[column])
return sum(column_values) / len(column_values)
答案 2 :(得分:0)
让我们来看看这段代码:
def averager(filename):
averager
作为名称并不尽如人意。例如averagecsv
怎么样?
f=open(filename, "r")
avg=f.readlines()
avg
命名不佳。这不是一切的平均值!这是一堆线。例如,将其称为csvlines
。
f.close()
avgr=[]
avgr
命名不佳。它是什么?名字应该是有意义的,否则为什么要给他们?
final=""
x=0
i=0
while i < range(len(avg[0])):
while x < range(len(avg)):
如评论中所述,您可以将这些替换为for循环,如for i in range(len(avg[0])):
中所示。这使您无需声明和增加有问题的变量。
avgr+=str((avg[x[i]]))
咦?让我们打破这一行。
命名不佳的avg
是来自csv文件的行。
所以,我们用x索引avg
,好吧,这会给我们提供行号x
。但是...... x [i]没有意义,因为x是一个整数,而整数不支持数组访问。我想你在这里要做的是......将文件分成行,然后将行分成列,因为它是csv。正确?
所以让我们放弃代码。你想要这样的东西,使用split http://docs.python.org/2/library/stdtypes.html#str.split函数:
totalaverage = 0
for col in range(len(csvlines[0].split(","))):
average = 0
for row in range(len(csvlines)):
average += int(csvlines[row].split(",")[col])
totalaverage += average/len(csvlines)
return totalaverage
等等!还有更多! Python有一个内置的csv解析器比分割,
更安全。请在此处查看:http://docs.python.org/2/library/csv.html
答案 3 :(得分:0)
在回应OP询问他应该如何在其中一条评论中提及这一点时,我的建议如下:
import csv
from collections import defaultdict
with open('numcsv.csv') as f:
reader = csv.reader(f)
numbers = defaultdict(list) #used to avoid so each column starts with a list we can append to
for row in reader:
for column, value in enumerate(row,start=1):
numbers[column].append(float(value)) #convert the value to a float 1. as the number may be a float and 2. when we calc average we need to force float division
#simple comprehension to print the averages: %d = integer, %f = float. items() goes over key,value pairs
print('\n'.join(["Column %d had average of: %f" % (i,sum(column)/(len(column))) for i,column in numbers.items()]))
产
>>>
Column 1 had average of: 2.400000
Column 2 had average of: 2.000000
Column 3 had average of: 1.800000
对于文件:
1,2,3
1,2,3
3,2,1
3,2,1
4,2,1
答案 4 :(得分:0)
这是两种方法。第一个只是获得该行的平均值(上面的代码看起来像是在做什么)。第二个得到一列的平均值(这是你提出的问题)
''' This just gets the avg for a line'''
def averager(filename):
f=open(filename, "r")
avg = f.readlines()
f.close()
count = 0
for i in xrange(len(avg)):
count += len(avg[i])
return count/len(avg)
''' This gets a the avg for all "columns"
char is what we split on , ; | (etc)
'''
def averager2(filename, char):
f=open(filename, "r")
avg = f.readlines()
f.close()
count = 0 # count of items
total = 0 # sum of all the lengths
for i in xrange(len(avg)):
cols = avg[i].split(char)
count += len(cols)
for j in xrange(len(cols)):
total += len(cols[j].strip()) # Remove line endings
return total/float(count)