如何在大型文本文件中查找特定元素的平均值

时间:2019-01-31 22:01:51

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

我正在尝试实现以下预期输出部分中说明的内容。文本文件每行包含5个浮点数,最后一个无用,因为它仅对前面的数字表示它是真实账单还是假账单进行分类(0为假账单,1为真实账单)。我想创建一个循环,该循环可以采用每行的第一个数字(有600多个行)并找到平均值,与每行的第二个数字相同,分别为第三和第四。输出应为显示每个平均值[avg1 avg2 avg3 avg4]的列表。下面的代码可以成功完成此操作,但一次只能完成一次。例如。在这行总和+ = 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]。中点就是我们将用作分类器的地方。

2 个答案:

答案 0 :(得分:0)

我不太了解您的问题,但是我可以回答其中的一部分。

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

我会使用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'})

答案 1 :(得分:0)

您不需要安装sprintf之类的已安装库,尽管它们确实具有易于使用的功能来计算表的平均值。

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

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)