Python-计算csv fi中每个列的平均值

2024-04-20 09:47:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我是Python的新手,我正在尝试获取csv文件的每个(列或行)的平均值,然后选择高于其列(o行)平均值两倍的值。我的文件有数百列,并且有如下浮点值:

845.123,452.234,653.23,...
432.123,213.452.421.532,...
743.234,532,432.423,...

我已经尝试了对代码的一些更改,以获得每一列的平均值(分别),但目前我的代码是这样的:

def AverageColumn (c):
    f=open(csv,"r")
    average=0
    Sum=0
    column=len(f)
    for i in range(0,column):
        for n in i.split(','):
            n=float(n)
            Sum += n
        average = Sum / len(column)
    return 'The average is:', average

    f.close()


csv="MDT25.csv"
print AverageColumn(csv)

但是我总是得到一个错误,比如“f没有len()”或者“int”对象不可iterable”。。。

如果有人告诉我如何获得每一列(或每一行)的平均值,然后选择高于其列(或每一行)平均值两倍的值,我将非常感激。我宁愿不将模块作为csv导入,但如您所愿。谢谢!


Tags: 文件csv代码inforlendefcolumn
3条回答

这是对你的函数的清理,但它可能不做你想做的事情。 目前,它正在获取所有列中所有值的平均值:

def average_column (csv):
    f = open(csv,"r")
    average = 0
    Sum = 0
    row_count = 0
    for row in f:
        for column in row.split(','):
            n=float(column)
            Sum += n
        row_count += 1
    average = Sum / len(column)
    f.close()
    return 'The average is:', average

我将使用csv模块(这使csv解析更容易),使用^{}对象管理列总数,使用context manager打开文件(不需要close()):

import csv
from collections import Counter

def average_column (csv_filepath):
    column_totals = Counter()
    with open(csv_filepath,"rb") as f:
        reader = csv.reader(f)
        row_count = 0.0
        for row in reader:
            for column_idx, column_value in enumerate(row):
                try:
                    n = float(column_value)
                    column_totals[column_idx] += n
                except ValueError:
                    print "Error -- ({}) Column({}) could not be converted to float!".format(column_value, column_idx)                    
            row_count += 1.0            

    # row_count is now 1 too many so decrement it back down
    row_count -= 1.0

    # make sure column index keys are in order
    column_indexes = column_totals.keys()
    column_indexes.sort()

    # calculate per column averages using a list comprehension
    averages = [column_totals[idx]/row_count for idx in column_indexes]
    return averages

如果出于某种原因,您希望不使用stdlib模块:

with open('path/to/csv') as infile:
    columns = list(map(float,next(infile).split(',')))
    for how_many_entries, line in enumerate(infile,start=2):
        for (idx,running_avg), new_data in zip(enumerate(columns), line.split(',')):
            columns[idx] += (float(new_data) - running_avg)/how_many_entries

首先,正如人们所说的-CSV格式看起来很简单,但它可能非常不平凡,特别是一旦字符串进入播放。monkut已经为您提供了两个解决方案,一个是清理后的代码版本,另一个是使用CSV库的解决方案。我将给出另一个选择:没有库,但是有大量的惯用代码可供仔细研究,这将同时给出所有列的平均值。

def get_averages(csv):
    column_sums = None
    with open(csv) as file:
        lines = file.readlines()
        rows_of_numbers = [map(float, line.split(',')) for line in lines]
        sums = map(sum, zip(*rows_of_numbers))
        averages = [sum_item / len(lines) for sum_item in sums]
        return averages

注意事项:在代码中,f是一个文件对象。您尝试在返回值后关闭它。这段代码永远不会到达:在处理return之后,不会执行任何操作,除非您有try...finally构造或with构造(就像我正在使用的-它将自动关闭流)。

map(f, l),或等效的[f(x) for x in l],创建一个新列表,其元素通过对l上的每个元素应用函数f获得。

f(*l)将在函数调用之前“解压”列表l,将每个元素作为单独的参数赋给函数f

相关问题 更多 >