在列表上迭代函数,并追加返回的值

时间:2013-01-07 17:43:25

标签: python function counter average

我有一个CSV数据集,40列乘800行。 但举个例子可以说它看起来像这样:

Ref  X  Y
11   1  10 
11   2  9
11   3  8
11   4  7
12   5  6 
12   6  5
12   7  4
13   8  3
13   9  2

如何定义一个返回每个Ref的平均X和Y值列表的函数?产生类似的东西:

Ref_list = [11,12,13]        
Av_X = [2.5,6,12.5]

我怀疑这是接近它的最好方法,但我写了以下代码:

my_data = genfromtxt('somedata.csv', delimiter=',',skiprows=1) 

X=[]
for i in my_data:
    X.append(i[0])
    counter=collections.Counter(X)
    keys=np.sort((counter.keys())) #find and sort ref key values

def getdata():
    X , Y = [], []
    for i in my_data:
       if i[0] == refs:
           X.append(i[1])
           Y.append(i[2])
    AV_X=np.average(X)
    AV_Y=np.average(X)
    return AV_X, AV_Y

for refs in keys: # run function over key range 
    AV_X, AV_Y = getdata()

这里我卡住了,我试图在ref no范围内迭代函数。 (键)并附加返回的值。但除了错误,我只能得到最后一个Ref的值。在钥匙。

我想有更好的方法可以做到这一点,但我仍然是这个东西的新手。 非常感谢任何建议

5 个答案:

答案 0 :(得分:5)

您可以使用辉煌的pandas库来完成这些工作:

from StringIO import StringIO
import pandas as pd

df = pd.read_csv(StringIO('your_data'),
        delim_whitespace=True)

df.groupby('Ref').mean()

       X    Y
Ref          
11   2.5  8.5
12   6.0  5.0
13   8.5  2.5

正如你在最后一行所看到的那样,你在问题中算错了......

你也可以要求median, sum, max, etc..

答案 1 :(得分:1)

>>> A=np.array([[11,1,10,],[11,2,9],[11,3,8],[11,4,7],[12,5,6,],[12,6,5],[12,7,4],[13,8,3],[13,9,2]])
>>> A
array([[11,  1, 10],
       [11,  2,  9],
       [11,  3,  8],
       [11,  4,  7],
       [12,  5,  6],
       [12,  6,  5],
       [12,  7,  4],
       [13,  8,  3],
       [13,  9,  2]])
#Slice the data
>>> A[:,0]
array([11, 11, 11, 11, 12, 12, 12, 13, 13])
>>> refs=np.unique(A[:,0])
#Unique value of all references.
>>> refs
array([11, 12, 13])
#To get the average of each column
>>> np.average(A,axis=0)
array([ 11.77777778,   5.        ,   6.        ])

我想你想要这个吗?

#Create a mask
>>> A[:,0]==11
array([ True,  True,  True,  True, False, False, False, False, False], dtype=bool)
>>> Mask=A[:,0]==11
>>> A[Mask]
array([[11,  1, 10],
       [11,  2,  9],
       [11,  3,  8],
       [11,  4,  7]])
>>> np.average(A[Mask],axis=0)
array([ 11. ,   2.5,   8.5])
>>> np.vstack([np.average(A[A[:,0]==x],axis=0) for x in ref])
array([[ 11. ,   2.5,   8.5],
       [ 12. ,   6. ,   5. ],
       [ 13. ,   8.5,   2.5]])

所以最后你可以:

>>> refs=np.unique(A[:,0])
array([11, 12, 13])
>>> np.vstack([np.average(A[A[:,0]==x],axis=0) for x in ref])
array([[ 11. ,   2.5,   8.5],
       [ 12. ,   6. ,   5. ],
       [ 13. ,   8.5,   2.5]])

有一种更好的方法可以通过引入更高维度的矩阵来实现,这样就可以避免列表理解。

答案 2 :(得分:1)

import csv, collections, operator
def j(): return dict(X=[], Y=[])
def mean(inlist): return operator.truediv(sum(inlist),len(inlist))
a = collections.defaultdict(j)
# get all the data
for line in csv.DictReader(open(myfile, 'r')):
    a[line['Ref']]['X'].append(line['X'])
    a[line['Ref']]['Y'].append(line['Y'])


# now, for the averages themselves

def get_avgs(inputlist, xy):
    return [mean(a[item][xy]) for item in inputlist]

使用:

get_avgs([11,12,13], 'X')
# returns:
[2.5,6,12.5]

答案 3 :(得分:1)

如果你愿意的话,你可以在一次通过中完成所有操作,而不先排序。

counts = {}
averages = {}
for line in data_file:
    ref = line[0]
    data = map(float, line[1:])
    if ref not in counts:
        counts[ref] = 1
        averages[ref] = data
    else:
        counts[ref] += 1
        averages[ref] = map(lambda running, new: ((running * (counts[ref] - 1)) + new) / counts[ref], averages[ref], data)

您可以将defaultdict用于countsaverages,但我认为在这种情况下,它对于清晰度或简洁性并没有真正的帮助。

如果你在2次传球中做到这一点可能会更有效率,但仍然没有排序。

counts = {}
totals = {}
for line in data_file:
    ref = line[0]
    data = map(float, line[1:])
    if ref not in counts:
        counts[ref] = 1
        totals[ref] = data
    else:
        counts[ref] += 1
        totals[ref] = map(lambda running, new: running + new, averages[ref], data)
averages = {ref : map(lambda total: total / counts[ref], totals[ref]) for ref in counts}

答案 4 :(得分:0)

我甚至不愿意为几十万行以下的任何东西打扰...为什么不用这个:

#assuming your data is a list of lists and you want the average of the 2nd column
avg = sum(x[1] for x in mydata) / len(mydata)

当然,如果您只想要匹配某个表达式的所有项目的平均值,请使用列表推导来过滤数据,然后计算结果列表中的平均值:

my_specific_data = [x[1] for x in mydata if x[0] == refs]
#... avg as above