以前の質問からの @jamylak による回答を参照し、わずかな変更を示しています。
結果のパターンを に一致x
させることもできますy
が、元のソリューションを変更して x と y をポイント (x,y) として扱うこともできます。
from itertools import groupby
x = [0,1,2,3,4,3,2,3,-2,-4,-7,2,2]
y = [0,1,2,3,4,5,6,7,8,9,10,11,12]
def slope(a,b): #Returns 1 for inc, 0 for equal and -1 for dec
return (a > b) - (a < b)
def groups(nums):
#
# Change the call to slope() to assume 2d point tuples as values
#
for k,v in groupby(zip(nums,nums[1:]), lambda (x,y): slope(x[0],y[0])):
yield next(v) + tuple(y for x,y in v)
#
# Pass in a zipped data structure
#
print list(groups(zip(x,y)))
# result
[((0, 0), (1, 1), (2, 2), (3, 3), (4, 4)),
((4, 4), (3, 5), (2, 6)),
((2, 6), (3, 7)),
((3, 7), (-2, 8), (-4, 9), (-7, 10)),
((-7, 10), (2, 11)),
((2, 11), (2, 12))]
結果のフォーマットがあなたにとって望ましいかどうかはわかりませんが。
それらを分離する方法は次のとおりです。
from operator import itemgetter
result = list(groups(zip(x,y)))
x = [map(itemgetter(0), points) for points in result]
y = [map(itemgetter(1), points) for points in result]
print x
# [[0, 1, 2, 3, 4], [4, 3, 2], [2, 3], [3, -2, -4, -7], [-7, 2], [2, 2]]
print y
# [[0, 1, 2, 3, 4], [4, 5, 6], [6, 7], [7, 8, 9, 10], [10, 11], [11, 12]]
または@jamylakが提案したように:
x,y = zip(*[zip(*points) for points in result])
groups()
また、メソッドの変更により N 次元のポイントまたはデータセットがどのように許可されるかについて、@jamylak が話していることを説明するために、次のように説明します。
z = ['foo',1,2,'bar',4,5,6,'foo',8,9,10,'bar',12]
print list(groups(zip(x,y,z)))
# result
[((0, 0, 'foo'), (1, 1, 1), (2, 2, 2), (3, 3, 'bar'), (4, 4, 4)),
((4, 4, 4), (3, 5, 5), (2, 6, 6)),
((2, 6, 6), (3, 7, 'foo')),
((3, 7, 'foo'), (-2, 8, 8), (-4, 9, 9), (-7, 10, 10)),
((-7, 10, 10), (2, 11, 'bar')),
((2, 11, 'bar'), (2, 12, 12))]
任意のデータセットであり、常にそれぞれの最初の要素でグループ化されていることがわかります。