我知道这个话题很难理解,但我不知道如何用一句话来描述我的问题... T ^ T
这是我想要做的事情。
我有一组三维的一维点。
A = [[0,1], [0,2], [0,3], [1,1], [2,1], [3,2], [3,3], [4,2], [4,3], [5,3], [6,3]]
第一个数字是x坐标,第二个数字是每个[]
中的标签我想在每对相邻点[x1,L1],[x2,L2]中插入一个切点,如果其中至少有一个具有多种标签,则L2属于不同于L1。;;;
例如,
[0,1], [0,2], [0,3]
它们都在x = 0上,但有三种标签
[1,1]
只属于一个类别,所以我想在0和1的中间添加一个切点x = 0.5。
3 x
2 x
1 x 1
x
0-x-1-
但是喜欢
[1,1] and [2,1]
它们都只有一个相同的标签,这里不需要添加切割点。
所以结果应该是
[0.5, 2.5, 3.5, 4.5]
也许看起来像这样
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
我想写的代码看起来像这个表格
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)
但是我坚持使用#&#34;除了j&#34; 在这种情况下,只有3个类别,所以也许我可以手动完成,但我正在寻找一种更聪明的方法,所以每次遇到新数据时我都不需要重写这个部分。不同数量的类别。
除了j&#34之外,还有什么功能我可以用来做&#34;操作??
任何评论或回答都将不胜感激。 在此先感谢T ^ T
答案 0 :(得分:2)
您可以不使用,例如:X[i+1] not in group[j]
其次,您的算法似乎过于复杂。这是什么东西?
A = [[0,1], [0,2], [0,3], [1,1], [2,1], [3,2], [3,3], [4,2], [4,3], [5,3], [6,3]]
point, label = A[0]
cuts = []
for npoint, nlabel in A[1:]:
if not npoint == point:
if not label == nlabel:
cuts.append((point+npoint)/2.)
point = npoint
label = nlabel
答案 1 :(得分:2)
这是你遇到的一个奇怪的问题,但这是一个功能性的方法。
from itertools import groupby
groupby
将让我们轻松合并您的X坐标,假设数组已按预先排序。
l = [(i, [x[1] for x in g]) for i, g in groupby(A, lambda x: x[0])]
这看起来有点令人生畏,但在概念上非常简单。 groupby
将所有共享X的东西汇集在一起,内部列表理解只是将X值转储出来:
l
[(0, [1, 2, 3]),
(1, [1]),
(2, [1]),
(3, [2, 3]),
(4, [2, 3]),
(5, [3]),
(6, [3])]
然后,如果我们使用zip
将每个元素与下一个元素组合在一起,我们可以选择符合条件的对并获得它们之间的中点:
[(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]