Chu - 1 year ago 52
Python Question

# How to define an element belongs to other categories?

I know the topic is really hard to understand but I don't know how to describe my problem in one sentence...T^T

Here is what I'm trying to do.

I have a set of 1-dimensional points in three categories.

``````A = [[0,1], [0,2], [0,3], [1,1], [2,1], [3,2], [3,3], [4,2], [4,3], [5,3], [6,3]]
``````

First number is x-coordinate and second number is label in each [ ]

And I want to insert a cut point into every pair of adjacent points [x1, L1], [x2, L2] if at least one of them has more than one kinds of label and L2 belongs to those categories that differ from L1.;;;

For example,

``````[0,1], [0,2], [0,3]
``````

they are all on x = 0 but there are three kinds of labels

``````[1,1]
``````

belongs to only one categories, so I would like to add a cut point x=0.5 in the middle of 0 and 1.

``````3 x
2 x
1 x 1
x
0-x-1-
``````

but like

``````[1,1] and [2,1]
``````

they both has only one and identical label, there is no need to add a cut point here.

So the result should be
`[0.5, 2.5, 3.5, 4.5]`

and maybe looks like this

`````` 3 x       x 3 x 3 x 3   3     <--Label
2 x       x 2 x 2 x           <--Label
1 x 1   1 x   x   x           <--Label
x       x   x   x
-0-x-1---2-x-3-x-4-x-5---6---  <--X-axis
0.5     2.5 3.5 4.5          <--Cut points
``````

The code I want to write will looks like this form

``````A = [[0,1], [0,2], [0,3], [1,1], [2,1], [3,2], [3,3], [4,2], [4,3], [5,3], [6,3]]
X = []
for a in A:
X.append(a[0])
X = sorted(list(set(X)))

labels = [[1], [2], [3]]
group = []
for i in range(len(labels)):
group.append([])

for a in A:
for i in range(3):
if a[1] in labels[i]:
group[i].append(a[0])

cutpoints = []

for i, x in enumerate(X):
for j in range(len(group)):
if x in group[j] and (X[i+1] in group[ other than j ]):
cutpoints.append((x+X[i+1])/2)
``````

But I stuck at the part "other than j"
In this case there are only 3 categories so maybe I can do that manually but I'm looking for a more clever way to do it so I don't need to rewrite this part every time I meet a new data with different number of categories.

Is there any function I can use to do the "other than j" operation??

Any comment or answer will be appreciated.

This is sort of a weird problem you've got, but here's a functional way to do.

``````from itertools import groupby
``````

`groupby` will let us easily merge your X coordinates, assuming the array is pre-sorted by them.

``````l = [(i, [x[1] for x in g]) for i, g in groupby(A, lambda x: x[0])]
``````

This looks a bit daunting, but is conceptually pretty easy. The `groupby` pulls together all the things that share an X, and the inner list comprehension just dumps the X values out:

``````l

[(0, [1, 2, 3]),
(1, [1]),
(2, [1]),
(3, [2, 3]),
(4, [2, 3]),
(5, [3]),
(6, [3])]
``````

Then if we group each together with the next element using `zip` we can just pick out the pairs that meet your criteria and get the midpoint between them:

``````[(i1+i2) / 2.
for (i1, l1), (i2, l2)
in zip(l, l[1:])
if l1 != l2 or len(l1) > 1]

[0.5, 2.5, 3.5, 4.5]
``````