在R中,您可以根据另一个向量的因子分割向量:
> a <- 1:10
[1] 1 2 3 4 5 6 7 8 9 10
> b <- rep(1:2,5)
[1] 1 2 1 2 1 2 1 2 1 2
> split(a,b)
$`1`
[1] 1 3 5 7 9
$`2`
[1] 2 4 6 8 10
因此,根据另一个列表的值(根据因子的顺序)对列表(根据python)进行分组。
除了itertools.groupby
方法之外,python中有什么方便吗?
答案 0 :(得分:4)
从您的示例中,看起来b中的每个元素都包含将存储节点的1索引列表。 Python缺少R似乎拥有的自动数字变量,因此我们将返回一个列表元组。如果你可以做零索引列表,并且你只需要两个列表(例如,对于你的R用例,1和2是唯一的值,在python中它们将是0和1)
>>> a = range(1, 11)
>>> b = [0,1] * 5
>>> split(a, b)
([1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
然后您可以使用itertools.compress
:
def split(x, f):
return list(itertools.compress(x, f)), list(itertools.compress(x, (not i for i in f)))
如果您需要更多一般输入(多个数字),类似下面的内容将返回一个n元组:
def split(x, f):
count = max(f) + 1
return tuple( list(itertools.compress(x, (el == i for el in f))) for i in xrange(count) )
>>> split([1,2,3,4,5,6,7,8,9,10], [0,1,1,0,2,3,4,0,1,2])
([1, 4, 8], [2, 3, 9], [5, 10], [6], [7])
答案 1 :(得分:0)
你可以尝试:
a = [1,2,3,4,5,6,7,8,9,10]
b = [1,2,1,2,1,2,1,2,1,2]
split_1 = [a[k] for k in (i for i,j in enumerate(b) if j == 1)]
split_2 = [a[k] for k in (i for i,j in enumerate(b) if j == 2)]
结果:
In [22]: split_1
Out[22]: [1, 3, 5, 7, 9]
In [24]: split_2
Out[24]: [2, 4, 6, 8, 10]
为了使这一概括,您可以简单地遍历b:
中的唯一元素splits = {}
for index in set(b):
splits[index] = [a[k] for k in (i for i,j in enumerate(b) if j == index)]
答案 2 :(得分:0)
编辑:警告,这是一个groupby
解决方案,这不是OP所要求的,但它可能对某人寻找一种不太具体的方式来分割R方式有用在Python中。
这是itertools
的一种方式。
import itertools
# make your sample data
a = range(1,11)
b = zip(*zip(range(len(a)), itertools.cycle((1,2))))[1]
{k: zip(*g)[1] for k, g in itertools.groupby(sorted(zip(b,a)), lambda x: x[0])}
# {1: (1, 3, 5, 7, 9), 2: (2, 4, 6, 8, 10)}
这会为您提供一个字典,类似于您从R split
获得的命名列表。
答案 3 :(得分:0)
作为R的长期用户,我想知道如何做同样的事情。这是用于对向量进行制表的非常方便的功能。这是我想出的:
a = [1,2,3,4,5,6,7,8,9,10]
b = [1,2,1,2,1,2,1,2,1,2]
from collections import defaultdict
def split(x, f):
res = defaultdict(list)
for v, k in zip(x, f):
res[k].append(v)
return res
>>> split(a, b)
defaultdict(list, {1: [1, 3, 5, 7, 9], 2: [2, 4, 6, 8, 10]})