【问题标题】:How to find averages of specific elements in a large text file如何在大型文本文件中查找特定元素的平均值
【发布时间】:2019-02-01 07:32:01
【问题描述】:

我正在尝试实现预期输出部分中的以下说明。文本文件每行包含 5 个浮点数,最后一个没有用,因为它只是对前面的数字表示它是真钞还是假钞进行分类(0 是假的,1 是真的)。我想创建一个循环,它可以获取每行的第一个数字(有 600 多行)并找到平均值,与每行的第二个数字相同,第三个和第四个。输出应该是一个列表,显示每个平均值 [avg1 avg2 avg3 avg4]。下面的代码可以成功地做到这一点,但一次只能一个。例如。在这一行 sum += float(line.split()[0]) 中,将 0 更改为 1 将给出每行中第二个数字的平均值,依此类推。如何创建一个高效的循环来一次提供所有平均值?

我已经尝试为每个数字“列”复制循环并粘贴 4 次,但效率低且不起作用。

import web_scraper
import urllib.request
import math

def data_text_files():

page = 'http://archive.ics.uci.edu/ml/machine-learning- 
databases/00267/data_banknote_authentication.txt'
stream = urllib.request.urlopen(page)

samples = web_scraper.get_all_data(stream, ',')

training = open("training2.txt", "w")
testing = open ("testing2.txt", "w")

for i in range(len(samples)):
    if i % 2 == 0:
        #write data to training file
        count = 1
        for bill in samples[i]:
            bill_str = str(bill)
            if(count == 5):
                training.write(bill_str + "\n")
                count = 1
            else:
                training.write(bill_str + " ")
                count += 1

    else:
        #write data to testing file
        count = 1
        for bill in samples[i]:
            bill_str = str(bill)
            if(count == 5):
                testing.write(bill_str + "\n")
                count = 1
            else:
                testing.write(bill_str + " ")
                count += 1



data_text_files()



with open('training2.txt') as fh:
    sum = 0  # initialize here, outside the loop
    count = 0  # and a line counter
    for line in fh:
        count += 1  # increment the counter
        sum += float(line.split()[0])  # add here, not in a nested loop


    average = [sum / count]

    print (average)








 building_classifier()

每个数据样本有4个属性(不包括最后一个表示样本分类的属性)。所以,数据看起来像这样:

  [ [2, 4, 6, 8, 0],
    [4, 6, 8, 10,  0],
    [1, 3, 5, 7, 1]
    [3, 5, 7, 9,  1]]

要构建分类器,您将使用“training.txt”中的数据:

计算具有相同分类(0 或 1)的所有样本中每个属性的平均值。对于上面显示的数据,假冒样本 (0) 中每个属性的平均值为 [3, 5, 7, 9],而真实样本 (1) 的平均值为 [2, 4, 6, 8]。 通过将假冒样本的平均值和真实样本的平均值相加,找到 2 组平均值之间的中点,然后将结果除以 2。这将为每个属性完成。因此,对于显示的数据,中点将是 [2.5, 4.5, 6.5, 8.5]。我们将使用中点作为分类器。

【问题讨论】:

  • 你的问题有点太宽泛了。您只需要获得平均值的帮助,而不是分类器,对吗?如果您可以发布输入文件的外观示例,将会很有帮助
  • 您示例中的大部分代码与您的问题无关,问题实际上仅始于with open('training2.txt') as fh:。此外,尽管该部分似乎正确缩进,但它前面的代码不是,让每个试图理解问题的人都难以阅读 - 请更正。

标签: python loops floating-point text-files classification


【解决方案1】:

我不太明白你的问题,但我可以回答这部分。

“计算所有具有相同分类的样本的每个属性的平均值”

我会使用 pandas 从文件中创建一个数据框,然后添加列标题:

import pandas as pd

df = pd.read_csv('input_file.txt', sep=" ", header=None)
data.columns = ['a', 'b', 'c', 'd', 'e']

然后我会为每一列使用 pandas groupby 和聚合方法:

aggregate = df.groupby(['e'])
a_column_mean = aggregate.agg({'a': 'mean'})
b_column_mean = aggregate.agg({'b': 'mean'})
c_column_mean = aggregate.agg({'c': 'mean'})
d_column_mean = aggregate.agg({'d': 'mean'})

【讨论】:

    【解决方案2】:

    您不需要安装像 pandas 这样的库,尽管它们确实具有易于使用的函数来计算表格的平均值。

    您的代码计算单个总和并计算行数,然后从中计算单个平均值。您想在同一个循环中计算所有四个平均值。您可以通过一次读取整个文件来更轻松地做到这一点,但我会坚持使用您的方法,因为这对于非常大的文件很重要:

    with open('training2.txt') as fh:
        n = 4  # number of fields we're interested in
        sums = [0] * n  # initialize here, outside the loop
        count = 0  # and a line counter
        for line in fh:
            count += 1  # increment the counter
            fields = line.split()  # split the line outside the loop, only once
            for i in range(n):
                sums[i] += float(fields[i])  # add here, not in a nested loop
    
        averages = [s / count for s in sums]  # not using the name sum, as it is a built-in
    
        print(averages)
    

    这是假设您的代码有效并且您的文本文件实际上具有由空格分隔的值,否则您需要类似 .split(',')

    【讨论】:

      猜你喜欢
      • 2017-06-30
      • 2017-04-20
      • 2017-02-18
      • 2013-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多