2013-08-27 19 views
0

我正在编写一个代码来对数据进行分类,并获得平均值和标准偏差。这里是我的数据的例子。对数据进行分类,计算每个类别的平均值和标准差

3917 1 -0.662261 25.148 22.9354 68.8076 
3918 1 12.7649 18.7451 7.68473 69.0063 
3919 1 -9.56836 -23.3265 -61.953 68.8357 
3920 1 11.6292 31.6525 -29.3697 69.1372 
3921 2 26.4837 -66.7897 12.0257 69.2282 
3922 1 -9.81652 14.3788 9.38343 69.1217 
3923 2 39.931 -88.1879 109.498 69.1604 
3924 1 4.5502 3.53887 -6.59604 69.486 
3925 2 13.6801 -24.6628 -5.7568 69.9398 
3926 1 -10.5635 7.05517 -8.82785 70.2263 

正如你所看到的,有6列。我正在考虑三步计算。

  1. 根据第6列对这些数字进行分类。第6列由0〜n的浮点数组成。我希望生成n个部分(或子矩阵,或其他),如0〜1,1〜2,2〜3 .... n-1〜n。最后一个数字应该是最后一个数据的数字,因为我希望能够创建部分。例如,如果最后一个数字是121.2513,最后一部分应该是120〜121以包含该数据。

  2. 将列1〜5的所有其他数字重新分配给基于第6列的相应子部分。如果在特定部分中没有编号,则将其打印为0.将会有n个小节。每个小节中的元素数量将是随机的。

  3. 得到每个子段的第3,第4和第5列的平均值和标准偏差,并将输入文件写入输入文件中,第'小节中的元素数,小节的开始数以及第3小节的平均值和标准差,第4列和第5列'

我正在尝试使用多个for循环,但它变得太复杂,并且会出错。有没有其他简单的方法来分类数据,与每个子部分一起玩,并用Python打印出来?另外,我的for循环根本不起作用。任何简单的示例建议使用这些数据?

+2

请编辑您的文章以包括您的* for循环根本不工作* ...部分 –

+1

您是否在使用[numpy](http://www.numpy.org)?如果不是,你有没有理由不能?它使得这种代码变得简单很多(与scipy和/或pandas一起),并避免了所有显式循环,使得你无法正确使用。 – abarnert

+0

你可以发布你迄今为止写的代码吗? – scohe001

回答

2

这个任务适合熊猫图书馆。 (http://pandas.pydata.org/)根据我对你的帖子的理解,你想要计算列方法和标准偏差。要计算行方向统计量,请将参数axis=1添加到平均值和std函数中。 在下面的代码,示例性已被保存到“tmp.txt”的第一个步骤将其加载;然后它是简单在数据帧,以计算统计

import pandas as pd 
df =pd.read_csv('tmp.txt',sep=' ',header=None) 
means = df.mean() 
stds = df.std() 

有关大熊猫的更多信息,取看快速介绍:http://pandas.pydata.org/pandas-docs/stable/10min.html

+0

我可以询问'分类'部分吗?如何使用numpy或pandas对基于第6列值的所有数据进行分类? – exsonic01

+0

我不确定你的意思,但你可以执行各种选择和分组操作。例如,假设您只想计算第6列(列名称5)> = 69中具有值的行的标准偏差。这只是:'df [df [5]> = 69] .std()'对于列中的分类值,也可以使用'groupby()'运算符。看看'10分钟到熊猫'的链接 - 它提供了更多细节。 – user1470788

0

我假设你有一个列表列表中的矩阵,并告诉你如何开始(但是,正如我在评论中提到的,如果你有你的矩阵在一个numpy arraymatrix,这一切都会更容易 - 也更快。)


如果你只是有一个值作为一个大的多行字符串,你可以将其转换成类似这样的浮点值列表的列表:

m = [[float(col) for col in line.split()] for line in s.splitlines()] 

现在,通过“分类基于这些数字在第6列“,这听起来是你想要的是按照该列的整数值对它们进行分组。

Python自带一个groupby函数,它可以完成您想要的大部分功能,但您必须先对数据进行排序。

在Python中,排序和分组以及相关函数总是让您传递一个关键函数。您不必对第6列进行排序和分组,您可以使用第6列作为关键字对整行进行排序和分组。

但实际上,你不想使用第6列的值作为关键字,你想使用整数值的第6列。对于前者,你会使用自带的STDLIB的itemgetter功能,但这样做更复杂的东西,你最好写它的函数:

def keyfunc(row): 
    return int(row[5]) 
groups = groupby(sorted(data, key=keyfunc), key=keyfunc) 

(如果你反复这样做,你可能希望编写一个包装函数,用相同的密钥对组进行排序,所以你不必重复自己,并且弄错了它。)

这是什么给你的是一个带有迭代器的迭代器,它有点难打印出来:

[(k, list(g)) for k, g in groups] 

但你得到的是:

[(68, 
    [[3917.0, 1.0, -0.662261, 25.148, 22.9354, 68.8076], 
    [3919.0, 1.0, -9.56836, -23.3265, -61.953, 68.8357]]), 
(69, 
    [[3918.0, 1.0, 12.7649, 18.7451, 7.68473, 69.0063], 
    [3920.0, 1.0, 11.6292, 31.6525, -29.3697, 69.1372], 
    [3921.0, 2.0, 26.4837, -66.7897, 12.0257, 69.2282], 
    [3922.0, 1.0, -9.81652, 14.3788, 9.38343, 69.1217], 
    [3923.0, 2.0, 39.931, -88.1879, 109.498, 69.1604], 
    [3924.0, 1.0, 4.5502, 3.53887, -6.59604, 69.486], 
    [3925.0, 2.0, 13.6801, -24.6628, -5.7568, 69.9398]]), 
(70, [[3926.0, 1.0, -10.5635, 7.05517, -8.82785, 70.2263]])] 

所以,每个k是整数的类别进行分组,并且每个g是所有该类别中的行(排序顺序)。

(需要注意的是,因为groups是一个迭代器,如果你print此,groups现在是空的。)

这需要你的第一个问题的关心,我想大多数你的第二个的(我不确定你到底想要什么)。

对于第三个,你首先需要遍历组:

for k, g in groups: 

如果你多次去遍历组,要立即它的列表,然后遍历该清单。

对于每个组,您想对一些列进行统计。最简单的方法就是使用一个模块来处理所有的数学问题。 PyPI上的stats模块是一个不错的选择,特别是现在(稍有变化),它可能最终会在即将到来的Python版本的标准库中出现。

但我只是显示平均值,因为这是微不足道的。

所以:

def mean(sequence): 
    return sum(sequence)/len(sequence) 

for k, g in groups: 
    rows = list(g) 
    print(k) 
    for column_index in 2, 3, 4: 
     column = [row[column_index] for row in rows] 
     print(mean(column)) 

很可能有很多,这个代码不这样做,你所需要的,但我希望它足以让你开始,当你遇到问题要问更具体的问题。

0

正如其他人所说,你可能想看看numpy或pandas,特别是如果你的数据集很大。但是,在纯Python中以及正确的数据结构也很容易实现。在这种情况下,我只需使用defaultdict作为部分,关键是将第六列向下舍入,映射到列表元组(或更复杂的数据结构),然后您可以在其中收集列值:

from collections import defaultdict 
sections = defaultdict(lambda: ([], [], [], [], [])) 

with open("mydata.txt") as f: 
    #parse all non-empty lines into a list of lists of floats 
    lines = [x.strip() for x in f.read().split("\n")] 
    data = [map(float, x.split(" ")) for x in lines if x] 

for row in data: 
    #get the corresponding section (and create it if it doesn't exist) 
    section = sections[int(row[5])] 
    for x in range(5): 
     #append the column values to the respective lists 
     section[x].append(row[x]) 

现在sections包含易于使用的格式的数据;简单地遍历它,并计算您感兴趣的各行的平均值和标准偏差:

for s, columns in sections.items(): 
    #assuming "mean" is a function that calculates the average of a list 
    print "mean of section [%i,%i) column 3 is %f" % (s, s+1, mean(columns[2])) 

此扩展到多个/不同的列和函数应该是微不足道的。

+0

谢谢,但我需要在150多个小节中对数据进行分类。明确地写所有范围的类别将是太长,而不是'pythonic'的方式... – exsonic01

+0

@ user1798797“明确地写所有范围的类别” - 不知道你在说什么,我不知道你理解解。像打印每个部分的列的平均值可以用大约三行代码来完成,所以我不认为它“太长”...给我一点时间,我会为此写一些示例代码。 – l4mpi

相关问题