8

文本文件如下所示:

david weight_2005 50
david weight_2012 60
david height_2005 150
david height_2012 160
mark weight_2005 90
mark weight_2012 85
mark height_2005 160
mark height_2012 170

如何计算大卫的体重和身高平均值并标记如下:

david>> mean(weight_2005 and weight_2012), mean (height_2005 and height_2012)
mark>> mean(weight_2005 and weight_2012), mean (height_2005 and height_2012)

我不完整的代码是:

 import numpy as np
 import csv
 with open ('data.txt','r') as infile:
   contents = csv.reader(infile, delimiter=' ')
   c1,c2,c3 = zip(*contents)
   data = np.array(c3,dtype=float)

那么如何申请 np.mean??

4

4 回答 4

5

mean函数用于计算数字数组的平均值。您需要想出一种方法来c3通过对 应用条件来选择 的值c2

可能更适合您的需求的是将数据拆分为层次结构,我更喜欢使用字典。就像是

data = {}
with open('data.txt') as f:
    contents = csv.reader(f, delimiter=' ')
for (name, attribute, value) in contents:
    data[name] = data.get(name, {})  # Default value is a new dict
    attr_name, attr_year = attribute.split('_')
    attr_year = int(attr_year)
    data[name][attr_name] = data[name].get(attr_name, {})
    data[name][attr_name][attr_year] = value

现在data看起来像

{
    "david": {
        "weight": {
            2005: 50,
            2012: 60
        },
        "height": {
            2005: 150,
            2012: 160
        }
    },
    "mark": {
        "weight": {
            2005, 90,
            2012, 85
        },
        "height": {
            2005: 160,
            2012: 170
        }
    }
}

那么你能做的就是

david_avg_weight = np.mean(data['david']['weight'].values())
mark_avg_height = np.mean([v for k, v in data['mark']['height'].iteritems() if 2008 < k])

在这里,我仍在使用np.mean,但仅在普通 Python 列表中调用它。

于 2013-11-12T16:48:34.710 回答
4

我会制作这个社区 wiki,因为它更像是“我认为你应该这样做”而不是“这是你所提问题的答案”。对于这样的事情,我可能会使用pandas而不是numpy,因为它的分组工具要好得多。numpy与基于 - 的方法 进行比较也很有用。

import pandas as pd
df = pd.read_csv("data.txt", sep="[ _]", header=None, 
                 names=["name", "property", "year", "value"])
means = df.groupby(["name", "property"])["value"].mean()

..而且,呃,就是这样。


首先,将数据读入 a DataFrame,让空格或_单独的列:

>>> import pandas as pd
>>> df = pd.read_csv("data.txt", sep="[ _]", header=None, 
                 names=["name", "property", "year", "value"])
>>> df
    name property  year  value
0  david   weight  2005     50
1  david   weight  2012     60
2  david   height  2005    150
3  david   height  2012    160
4   mark   weight  2005     90
5   mark   weight  2012     85
6   mark   height  2005    160
7   mark   height  2012    170

然后按name和分组property,取value列,并计算平均值:

>>> means = df.groupby(["name", "property"])["value"].mean()
>>> means
name   property
david  height      155.0
       weight       55.0
mark   height      165.0
       weight       87.5
Name: value, dtype: float64

.. 好吧,这个sep="[ _]"技巧对于真正的代码来说有点太可爱了,尽管它在这里工作得很好。在实践中,我会使用空格分隔符,在第二列中读取,property_year然后执行

df["property"], df["year"] = zip(*df["property_year"].str.split("_"))
del df["property_year"]

允许在其他列中使用下划线。

于 2013-11-12T17:04:15.960 回答
2

您可以使用以下命令直接在 numpy 数组中读取数据:

data = np.recfromcsv("data.txt", delimiter=" ", names=['name', 'type', 'value'])

然后您可以使用 np.where 找到适当的索引:

指数 = np.where((data.name == 'david') * data.type.startswith('height'))

并对那些指数执行平均值:

np.mean(data.value[indices])
于 2013-11-12T16:58:13.097 回答
1

如果您的数据始终采用提供的格式。然后你可以使用数组切片来做到这一点:

(data[:-1:2] + data[1::2]) / 2

结果是:

[  55.   155.    87.5  165. ]
于 2013-11-12T16:54:58.303 回答