嗨,这是我的问题。我有一个程序可以计算列中数据的平均值。 实施例
Bob
1
2
3
输出
Bob
2
有些数据有'na' 所以对乔来说
Joe
NA
NA
NA
我希望此输出为NA
所以我写了一个if else循环
问题是它没有执行循环的第二部分而只打印出一个NA。有什么建议吗?
这是我的计划:
with open('C://achip.txt', "rtU") as f:
columns = f.readline().strip().split(" ")
numRows = 0
sums = [0] * len(columns)
numRowsPerColumn = [0] * len(columns) # this figures out the number of columns
for line in f:
# Skip empty lines since I was getting that error before
if not line.strip():
continue
values = line.split(" ")
for i in xrange(len(values)):
try: # this is the whole strings to math numbers things
sums[i] += float(values[i])
numRowsPerColumn[i] += 1
except ValueError:
continue
with open('c://chipdone.txt', 'w') as ouf:
for i in xrange(len(columns)):
if numRowsPerColumn[i] ==0 :
print 'NA'
else:
print>>ouf, columns[i], sums[i] / numRowsPerColumn[i] # this is the average calculator
文件如下:
Joe Bob Sam
1 2 NA
2 4 NA
3 NA NA
1 1 NA
,最终输出是名称和平均值
Joe Bob Sam
1.5 1.5 NA
好的,我尝试过罗杰的建议,现在我有这个错误:
追踪(最近一次通话): 文件“C:/avy14.py”,第5行,in 对于f中的行: ValueError:关闭文件的I / O操作
以下是这段新代码:
以open('C://achip.txt',“rtU”)为f: columns = f.readline()。strip()。split(“”) sums = [0] * len(列) rows = 0 对于f中的行: line = line.strip() 如果不是行: 继续
行+ = 1 for col,v in enumerate(line.split()): 如果sums [col]不是None: 如果v ==“NA”: sums [col] =无 其他: sums [col] + = int(v)
打开(“c:/chipdone.txt”,“w”)如下: 对于名称,压缩总和(列,总和): 打印>>输出,名称, 如果总和为无: 打印>>输出,“NA” 其他: print>> out,sum / rows
答案 0 :(得分:1)
with open("c:/achip.txt", "rU") as f:
columns = f.readline().strip().split()
sums = [0.0] * len(columns)
row_counts = [0] * len(columns)
for line in f:
line = line.strip()
if not line:
continue
for col, v in enumerate(line.split()):
if v != "NA":
sums[col] += int(v)
row_counts[col] += 1
with open("c:/chipdone.txt", "w") as out:
for name, sum, rows in zip(columns, sums, row_counts):
print >>out, name,
if rows == 0:
print >>out, "NA"
else:
print >>out, sum / rows
获取列名时我也会使用无参数版本的split(它允许你有多个空格分隔符)。
关于包含输入/输出示例的编辑,我保留了原始格式,输出将是:
Joe 1.75 Bob 2.33333333333 Sam NA
此格式是3行(ColumnName,Avg)列,但您可以根据需要更改输出。 :)
答案 1 :(得分:0)
使用numpy:
import numpy as np
with open('achip.txt') as f:
names=f.readline().split()
arr=np.genfromtxt(f)
print(arr)
# [[ 1. 2. NaN]
# [ 2. 4. NaN]
# [ 3. NaN NaN]
# [ 1. 1. NaN]]
print(names)
# ['Joe', 'Bob', 'Sam']
print(np.ma.mean(np.ma.masked_invalid(arr),axis=0))
# [1.75 2.33333333333 --]
答案 2 :(得分:0)
使用原始代码,我会添加一个循环并编辑print语句
with open(r'C:\achip.txt', "rtU") as f:
columns = f.readline().strip().split(" ")
numRows = 0
sums = [0] * len(columns)
numRowsPerColumn = [0] * len(columns) # this figures out the number of columns
for line in f:
# Skip empty lines since I was getting that error before
if not line.strip():
continue
values = line.split(" ")
### This removes any '' elements caused by having two spaces like
### in the last line of your example chip file above
for count, v in enumerate(values):
if v == '':
values.pop(count)
### (End of Addition)
for i in xrange(len(values)):
try: # this is the whole strings to math numbers things
sums[i] += float(values[i])
numRowsPerColumn[i] += 1
except ValueError:
continue
with open('c://chipdone.txt', 'w') as ouf:
for i in xrange(len(columns)):
if numRowsPerColumn[i] ==0 :
print>>ouf, columns[i], 'NA' #Just add the extra parts
else:
print>>ouf, columns[i], sums[i] / numRowsPerColumn[i]
此解决方案也以Roger的格式提供相同的结果,而不是您想要的格式。
答案 3 :(得分:0)
下面的解决方案更干净,代码行更少...
import pandas as pd
# read the file into a DataFrame using read_csv
df = pd.read_csv('C://achip.txt', sep="\s+")
# compute the average of each column
avg = df.mean()
# save computed average to output file
avg.to_csv("c:/chipdone.txt")
简化此解决方案的关键是将输入文本文件读入数据框的方式。熊猫read_csv允许您使用正则表达式指定sep / delimiter参数。在这种情况下,我们使用“ \ s +”正则表达式模式来确保列之间具有一个或多个空格。
一旦数据在数据框中,就可以使用简单的熊猫函数来计算平均值并将其保存到文件中。