2

I hoping someone can help me with a problem I'm stuck(again) with.

if i have coordinates:

 x = array[0,1,2,3,4,3,2,3,-2,-4,-7,2,2]
 y = array[0,1,2,3,4,5,6,7,8,9,10,11,12]

and with help in Categorizing the list of array in python, i could make:

x = [(0, 1, 2, 3, 4), (4, 3, 2), (2, 3), (3, -2, -4, -7), (-7, 2), (2, 2)]

The question is, how should i made y like this:

y = [(0,1,2,3,4),(4,5,6),(6,7),(7,8,9,10),(10,11),(11,12)]

since, x and y is actually coordinates and they bounded each other.

i have tried to use loop function, and i realize the code is still wrong

se = []
for i in range(len(z)):
        k = z[i]
        for i in range(len(k)):
                se.append(y[i])

best regards,

Glenn

2
  • 3
    You should really make this question all inclusive. I had no idea what you were talking about until I went and read through your previous question. Commented May 17, 2012 at 20:12
  • @jdi, ok. next time i'll be more careful. regards Commented May 18, 2012 at 5:07

4 Answers 4

3

I am referencing the answer by @jamylak from your previous question, and showing a slight modification.

While you could try and match the pattern of your resulting x to your y, you could also just modify the original solution to treat x and y as points (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))]

Though I am not sure if the resulting formatting is desirable to you.

Here is how you can separate them:

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]]

Or as suggested by @jamylak:

x,y = zip(*[zip(*points) for points in result])

And to illustrate what @jamylak was talking about, regarding how the modification to the groups() method allows for N-dimension points or data sets:

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))]

You can see that it can be any arbitrary data set, and its always just grouping on the first element of each.

Sign up to request clarification or add additional context in comments.

3 Comments

thanks for your reply. it's true the result is not desirable. since i'm hoping 'x' and 'y' is separated and they in same format like above. x = [(0, 1, 2, 3, 4), (4, 3, 2), (2, 3), (3, -2, -4, -7), (-7, 2), (2, 2)] y = [(0,1,2,3,4),(4,5,6),(6,7),(7,8,9,10),(10,11),(11,12)] because later on, i'll input them in my Lagrange formula. but i'll try to separate it now.
+1 I like this solution, since it uses the 0th element of each two consecutive points it supports any number of arrays eg. this also works with a list of z points. I would suggest replacing your last one liner with this: x,y = zip(*[zip(*points) for points in groups(zip(x,y))])
@jamylak: Great suggestions! I updated to illustrate your point.
2

The following does what you want:

x = [(0, 1, 2, 3, 4), (4, 3, 2), (2, 3), (3, -2, -4, -7), (-7, 2), (2, 2)]
y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

s = map(len, x)
s = [0] + [sum(s[:i])-i for i in range(1, len(s))] + [len(y)]
y = [tuple(y[a:b+1]) for a, b in zip(s, s[1:])]

Result:

>>> y
[(0, 1, 2, 3, 4), (4, 5, 6), (6, 7), (7, 8, 9, 10), (10, 11), (11, 12)]

This basically constructs a list of positions where y will be split. We figure this out using the length of each tuple in x, but it gets a little tricky because the last element of a set is included as the next element in the following set.

Here is one of the intermediate values which may help to clarify how this works:

>>> zip(s, s[1:])
[(0, 4), (4, 6), (6, 7), (7, 10), (10, 11), (11, 13)]

We use this to construct the new y like this:

[(0, 4), (4,  6), (6,  7), (7, 10), (10, 11), (11, 13)]
   \ |     \   \    \_  \
   | |      \  |      \  |
[y[0:4+1], y[4:6+1], y[6:7+1], ...]

1 Comment

i seeee! that's how it works! thanks man! thanks also for your explanation
0

A little ugly, but it works:

se = []
y2 = [y[0]]
i = 1
for xrun in x:
    first = True
    for xv in xrun:
        if first:
            first = False
            continue
        y2.insert( len(y2), y[i] )
        i += 1
    se.insert( len(se), tuple(y2) )
    y2 = [y[i-1]]

Comments

0

How about this one using numpy, it solves your first problem at the same time.

import numpy as np

x=(0, 1, 2, 3, 4, 3, 2, 3, -2, -4, -7, 2, 2)
y=range(13)

#First order differential, find slopes
dx = list((np.diff(x)>0)*1)

#First order differental looses first value, but we always want to keep it
#just decide if it's lower or higher than the 2nd value

d0=((x[0]-x[1])>0)*1

#Add the first order differential to the 2nd order differential (peaks)
ddx = [d0,]+list(np.abs(np.diff(dx)))

p=0
rx=[]
ry=[]

for n,v in enumerate(ddx):
    if v==1:
        rx.append(tuple(x[p:n+1]))
        ry.append(tuple(y[p:n+1]))
        p=n

print rx
print ry

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.