2010-09-27 40 views
17

我想在我写的一些Python代码中使用R中的子集命令的等价物。在Python中设置数据

这里是我的数据:

col1 col2 col3 col4 col5 
100002 2006 1.1 0.01 6352 
100002 2006 1.2 0.84 304518 
100002 2006 2 1.52 148219 
100002 2007 1.1 0.01 6292 
10002 2006 1.1 0.01 5968 
10002 2006 1.2 0.25 104318 
10002 2007 1.1 0.01 6800 
10002 2007 4 2.03 25446 
10002 2008 1.1 0.01 6408 

我想子集的基础上col1col2内容的数据。 (col1中的唯一值是100002和10002,col2是2006,2007和2008.)

这可以在R中使用子集命令完成,Python中是否有类似的东西?

回答

20

虽然基于迭代器的答案是完全正常的,如果你用numpy的阵列的工作(如你提到,你是)有更好更快的选择事情的方式:

import numpy as np 
data = np.array([ 
     [100002, 2006, 1.1, 0.01, 6352], 
     [100002, 2006, 1.2, 0.84, 304518], 
     [100002, 2006, 2, 1.52, 148219], 
     [100002, 2007, 1.1, 0.01, 6292], 
     [10002, 2006, 1.1, 0.01, 5968], 
     [10002, 2006, 1.2, 0.25, 104318], 
     [10002, 2007, 1.1, 0.01, 6800], 
     [10002, 2007, 4, 2.03, 25446], 
     [10002, 2008, 1.1, 0.01, 6408] ]) 

subset1 = data[data[:,0] == 100002] 
subset2 = data[data[:,0] == 10002] 

这就产生

SUBSET1:

array([[ 1.00002e+05, 2.006e+03, 1.10e+00, 1.00e-02, 6.352e+03], 
     [ 1.00002e+05, 2.006e+03, 1.20e+00, 8.40e-01, 3.04518e+05], 
     [ 1.00002e+05, 2.006e+03, 2.00e+00, 1.52e+00, 1.48219e+05], 
     [ 1.00002e+05, 2.007e+03, 1.10e+00, 1.00e-02, 6.292e+03]]) 

SUBSET2:

array([[ 1.0002e+04, 2.006e+03, 1.10e+00, 1.00e-02, 5.968e+03], 
     [ 1.0002e+04, 2.006e+03, 1.20e+00, 2.50e-01, 1.04318e+05], 
     [ 1.0002e+04, 2.007e+03, 1.10e+00, 1.00e-02, 6.800e+03], 
     [ 1.0002e+04, 2.007e+03, 4.00e+00, 2.03e+00, 2.5446e+04], 
     [ 1.0002e+04, 2.008e+03, 1.10e+00, 1.00e-02, 6.408e+03]]) 

如果您事先不知道第一列中的唯一值,则可以使用numpy.unique1d或内置函数set来查找它们。

编辑:我只是意识到你想选择,你有两列的独特组合......在这种情况下的数据,你可能会做这样的事情:

col1 = data[:,0] 
col2 = data[:,1] 

subsets = {} 
for val1, val2 in itertools.product(np.unique(col1), np.unique(col2)): 
    subset = data[(col1 == val1) & (col2 == val2)] 
    if np.any(subset): 
     subsets[(val1, val2)] = subset 

(我存储子集作为字典,关键是组合的元组... ...肯定还有其他的(更好的,取决于你在做什么)的方式来做到这一点!)

+0

谢谢!回想起来,这很明显,我应该自己尝试过,但你的解释非常完整。但是,您是否知道使用这种方法与迭代器相比可以提高多少速度?我认为迭代器也非常快! – user308827 2010-09-27 19:33:23

+0

@ user308827 - 它们是,但是如果你使用numpy数组而不是列表,那么使用numpy方法做事情会更快。一般来说,遍历整个numpy数组很慢。基于迭代器的解决方案必须遍历python中的每个元素。当您使用布尔numpy数组选择numpy数组的一个子集时,迭代在编译代码的幕后完成。 (我在这里简单化了,不过这就是要点)。基本上,如果您使用numpy数组来包含您的数据,那么使用numpy函数对它们进行操作会更快。 – 2010-09-27 19:44:22

+0

另外,有没有办法在子集中结合2个条件?例如,subset1 = data [(data [:,0] == 100002)和(data [:,1] == 2007)]似乎不起作用。谢谢! – user308827 2010-09-27 19:47:48

2

因为我不熟悉R,也不知道这个子集命令如何根据你的描述工作,所以我建议你看看itertool的groupby功能。如果给定一个输出值的函数,则可以根据该函数的输出形成组。取自groupby

groups = [] 
uniquekeys = [] 
data = sorted(data, key=keyfunc) 
for k, g in groupby(data, keyfunc): 
    groups.append(list(g))  # Store group iterator as a list 
    uniquekeys.append(k) 

然后你有你的子集。但是,请小心,因为返回的值不是完整的列表。他们是迭代器。

我假设你的值是逐行返回的。

+0

谢谢!这很有帮助。 – user308827 2010-09-27 19:32:40

5

subset() in R与Python中的filter()非常类似。由于参考笔记,这将是隐式列表解析使用,因此写的代码最简洁明了的方式可能是

[ item for item in items if item.col2 == 2006 ] 

如果,例如,您的数据行是在迭代称为items

+0

谢谢!我将添加过滤器到我的命令列表来记住 – user308827 2010-09-27 19:32:23