1

我有一个 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 的值。在键中。

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

4

5 回答 5

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

正如您在最后一行中看到的那样,您在问题中计算错误......

您也可以要求中位数、总和、最大值等。

于 2013-01-07T18:16:52.587 回答
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]])

有一种更好的方法可以通过引入更高维矩阵来避免列表理解。

于 2013-01-07T17:52:32.250 回答
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]
于 2013-01-07T18:06:22.867 回答
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)

您可以使用defaultdictforcountsaverages,但我认为在这种情况下,它并没有真正有助于清晰或简洁。

如果您分两遍进行,它可能会更有效,尽管仍然没有排序。

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}
于 2013-01-07T18:09:44.950 回答
0

对于低于几十万行的任何内容,我什至不会为 numpy 烦恼......为什么不直接使用它:

#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
于 2013-01-07T18:01:23.733 回答