我正在python中编写一个代码,用于完成一些事情的项目; 1)逐列读取xls文件中的数据 2)以三个为一组平均每列的列 3)然后平均得到的列
我已经完成了1和2,但似乎不能得到3,我认为我遇到的很多麻烦源于我使用浮点数然而我需要数字到6位小数。感谢任何帮助和耐心,我是python的新手
v = open("Pt_2_Test_Data.xls", 'wb') #created file to write output to
w = open("test2.xls")
count = 0
for row in w: #read in file
for line in w:
columns = line.split("\t") #split up into columns
date = columns[0]
time = columns[1]
a = columns[2]
b = columns[3]
c = columns[4]
d = columns[5]
e = columns[6]
f = columns[7]
g = columns[8]
h = columns[9]
i = columns[10]
j = columns[11]
k = columns[12]
l = columns[13]
m = columns[14]
n = columns[15]
o = columns[16]
p = columns[17]
q = columns[18]
r = columns[19]
s = columns[20]
t = columns[21]
u = columns[22]
LZA = columns[23]
SZA = columns[24]
LAM = columns[25]
count += 1
A = 0
if count != 0: # gets rid of column tiles
filter1 = ((float(a) + float(b) + float(c))/3)
filter1 = ("%.6f" %A)
filter2 = (float(d) + float(e) + float(f))/3
filter2 = ("%.6f" %filter2)
filter3 = (float(g) + float(h) + float(i))/3
filter3 = ("%.6f" %filter3)
filter4 = (float(j) + float(k) + float(l))/3
filter4 = ("%.6f" %filter4)
filter5 = (float(m) + float(n) + float(o))/3
filter5 = ("%.6f" %filter5)
filter6 = (float(p) + float(q) + float(r))/3
filter6 = ("%.6f" %filter6)
filter7 = (float(s) + float(t) + float(u))/3
filter7 = ("%.6f" %filter7)
A = [filter1, filter2, filter3, filter4, filter5, filter6, filter7]
A = ",".join(str(x) for x in A).join('[]')
print A
avg = [float(sum(col))/float(len(col)) for col in zip(*A)]
print avg
我也试过像这样格式化数据:
A = ('{0} {1} {2} {3} {4} {5} {6} {7} {8}'.format(date, time, float(filter1), float(filter2), float(filter3), float(filter4), float(filter5), float(filter6), float(filter7))+'\n') # average of triplets
print A
认为我可以访问每个列的值并通过调用它们来预先形成必要的数学,就像使用字典时那样,但这是不成功的:它似乎是将数据识别为一行(所以试图访问[0]的任何列超出范围)或单个字符,而不是数字列表。这与使用float函数有关吗?
答案 0 :(得分:1)
您可以使用decimal
模块显示确切的数字。
from decimal import *
getcontext().prec = 6 # sets the precision to 6
请注意,使用浮点表示:
print(Decimal(1)/(Decimal(7)) # 0.142857
print(Decimal(100)/(Decimal(7)) # results in 14.2857
这意味着您可能需要将精度设置为更高的值才能获得6个小数位... 例如:
from decimal import *
getcontext().prec = 28
print("{0:.6f}".format(Decimal(100) / Decimal(7))) # 14.285714
为了对您的问题给出完整的答案,您能否解释一下您所寻求的平均值?所有(21)列的平均值?你可以发一些test_data.xls吗?
答案 1 :(得分:1)
我不确定我理解你想在3)中平均哪些列,但也许这样做你想要的:
with open("test2.xls") as w:
w.next() # skip over header row
for row in w:
(date, time, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t,
u, LZA, SZA, LAM) = row.split("\t") # split columns into fields
A = [(float(a) + float(b) + float(c))/3,
(float(d) + float(e) + float(f))/3,
(float(g) + float(h) + float(i))/3,
(float(j) + float(k) + float(l))/3,
(float(m) + float(n) + float(o))/3,
(float(p) + float(q) + float(r))/3,
(float(s) + float(t) + float(u))/3]
print ('['+ ', '.join(['{:.6f}']*len(A)) + ']').format(*A)
avg = sum(A)/len(A)
print avg
您可以使用以下代码更简洁地做同样的事情:
avg = lambda nums: sum(nums)/float(len(nums))
with open("test2.xls") as w:
w.next() # skip over header row
for row in w:
cols = row.split("\t") # split into columns
# then split that into fields
date, time, values, LZA, SZA, LAM = (cols[0], cols[1],
map(float, cols[2:23]),
cols[23], cols[24], cols[25])
A = [avg(values[i:i+3]) for i in xrange(0, 21, 3)]
print ('['+ ', '.join(['{:.6f}']*len(A)) + ']').format(*A)
print avg(A)
答案 2 :(得分:0)
我会考虑使用numpy。我不确定如何阅读xls文件,但似乎有提供此功能的包。我会做这样的事情:
import numpy as np
with open("test2.txt") as f:
for row in f:
# row is a string, split on tabs, but ignore the values that
# don't go into the average. If you need to keep those you
# might want to look into genfromtxt and defining special datatypes
data = (np.array(row.split('\t')[2:23])).astype(np.float)
# split the data array into 7 separate arrays (3 columns each) and average on those
avg = np.mean(np.array_split(data,7))
print avg
我不确定上面的平均值是否正是你想要的。您可能需要保存较小的数组(smallArrays = np.array_split(data,7)
),然后迭代这些数组,计算平均值。
即使这不是你想要的,我也建议你看看numpy。我发现它非常容易使用,并且非常有用,就像你正在尝试进行计算一样。