-1
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__'
4

5 回答 5

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第 th 列求和,这可以通过推导轻松完成:

ith_col_sum = sum(float(line.split(',')[i]) for line in file_lines if line)

因此,为了将其平均,您可以将总和除以行数:

average = ith_col_sum / len(file_lines)
于 2013-05-01T04:04:49.010 回答
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)
于 2013-05-01T04:23:13.580 回答
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。正确的?

所以让我们抛弃代码。你想要这样的东西,使用拆分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

于 2013-05-01T04:17:04.083 回答
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
于 2013-05-01T04:29:38.447 回答
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)
于 2013-05-01T04:39:33.957 回答