【问题标题】:How to print specific pairs of a numpy array如何打印特定的numpy数组对
【发布时间】:2020-12-10 17:48:31
【问题描述】:

我想在一个 numpy 数组中创建特定的对,并用一个简单的打印函数展示我想要的东西。我有两个数组:

points=np.arange(1,15)

然后我有另一个数组:

repetition= np.array([4, 4, 2, 2, 1, 1])

现在,我想打印以下对(我刚刚写了评论以显示我想要的):

1 5 # first value of points and (1+4)th value of point
2 6 # second value of points and (2+4)th value of point
3 7 # third value of points and (3+4)th value of point
4 8 # fourth value of points and (3+4)th value of point
7 9 # seventh value of points and (6+2)th value of point
8 10 # eighth value of points and (8+2)th value of point
9 11 # ninth value of points and (9+2)th value of point
10 12 # tenth value of points and (10+2)th value of point
12 13 # twelfth value of points and (11+2)th value of point
13 14 # thirteenth value of points and (13+1)th value of point

我尝试了以下代码,但它没有给我预期的结果:

for m, n in zip (points, repetition):
    print (m, m+n)

在图中,我可视化了我的问题,其中红线显示了我的配对。我非常感谢您提前提供的任何帮助。

【问题讨论】:

  • 我一直在思考这个问题;出于好奇,应用程序是什么?
  • 我有几点意见。我正在连接这些点以创建线条。然后,我想使用我在该步骤中再次卡住的这些线创建表面:-(。我想在 Python 包中创建表面。
  • 哦,我明白了。我想您对Delaunay triangulation 很熟悉?顺便说一句,Matplotlib 可以选择在其Triangulation 类中为您使用该算法。 (记忆通道:我记得,早在九十年代初,在 C 中实现非常快的 Delaunay(和 Voronoi)。
  • 我对 Delaunay 三角剖分有一点了解,但我使用的是一个名为 gmsh [gmsh.info/] 的 Python 包,它为我创建了网格。我只需要将点导入其中。然后,通过给出点数(您的解决方案正在为我这样做),它会创建线条。然后我需要连接线来创建曲面,最后根据曲面制作网格。

标签: python numpy enumerate


【解决方案1】:

您实际上可以在 Python 中完成所有操作。由于您的图片似乎显示参差不齐的数组,因此在 numpy 中执行此操作可能会有点棘手。

from itertools import islice, zip_longest, count, tee

def pairwise(iterable):  # as per itertools recipes
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return zip(a, b)

def idx_pairs(repetitions):
    it = count()
    z = [list(islice(it, n))[::-1] for n in repetitions] 
    idx = sorted([
        (i, j) for seq in zip_longest(*z)
        for i, j in pairwise([k for k in seq if k is not None])])
    return idx

[(points[i], points[j]) for i, j in idx_pairs(repetition)]

输出

[(1, 5),
 (2, 6),
 (3, 7),
 (4, 8),
 (7, 9),
 (8, 10),
 (9, 11),
 (10, 12),
 (12, 13),
 (13, 14)]

为了更好地理解这些步骤,我建议检查:

  • z
  • idx
  • list(zip_longest(*z))

尤其是后者(直接在点上完成,而不是在点索引上),显示的内容与 OP 的绘图非常相似:

it = iter(points)
z = [list(islice(it, n))[::-1] for n in repetition]
list(zip_longest(*z))
# out:
[(4, 8, 10, 12, 13, 14),
 (3, 7, 9, 11, None, None),
 (2, 6, None, None, None, None),
 (1, 5, None, None, None, None)]

顺便说一句,看看repetition 列表不是单调递减时会发生什么很有趣:

repetition = np.array([4, 2, 4, 2, 1, 1])

it = iter(points)
z = [list(islice(it, n))[::-1] for n in repetition]
list(zip_longest(*z))

# out:
[(4, 6, 10, 12, 13, 14),
 (3, 5, 9, 11, None, None),
 (2, None, 8, None, None, None),
 (1, None, 7, None, None, None)]

我相信这样的repetition 的正确输出应该是:

[(1, 7),
 (2, 8),
 (3, 5),
 (4, 6),
 (5, 9),
 (6, 10),
 (9, 11),
 (10, 12),
 (12, 13),
 (13, 14)]

为了好玩,积分可以包含任何东西;下面是一个字符串示例:

points = [
    'foo', 'bar', 'hi', 'hello', 'world',
    'fuzz', 'ball', 'apple', 'tom', 'nancy',
    'fred', 'james', 'mary', 'bob', 'lisa', 
]
repetition = np.array([4, 2, 4, 2, 1, 1])
[(points[i], points[j]) for i, j in idx_pairs(repetition)]

# out:
[('foo', 'ball'),
 ('bar', 'apple'),
 ('hi', 'world'),
 ('hello', 'fuzz'),
 ('world', 'tom'),
 ('fuzz', 'nancy'),
 ('tom', 'fred'),
 ('nancy', 'james'),
 ('james', 'mary'),
 ('mary', 'bob')]

【讨论】:

  • oops -- 纠正一个小错误:如果重复不是单调递减...(例如[4, 2, 4, 2, 1, 1]...
  • 亲爱的@Pierre D,它没有产生我想要的东西。抱歉,我现在明白了。
  • 我已经修好了——你觉得有问题吗?
  • 不幸的是,是的,例如它给了我(5, 9),而我想要(7, 9)等等。如果您使用pairs 检查无花果或我的预期结果,您可以发现差异。感谢您的帮助,并感谢您花时间解决我的问题。
  • 哦,我明白了:需要颠倒那些参差不齐的列表。简单的修复——查看更新的答案。
【解决方案2】:

只有在@Pierre D. 的解释之后,我才真正理解了这个问题。谢谢。我更正了我之前的代码,并在里面放了一些打印功能以简化解释。

points=np.arange(1,15)
repetition= np.array([4, 4, 2, 2, 1, 1])

L=[]
k=0
for r in repetition:
    last= k+r
    L.append(points[k:last])
    k= last

print(L,"\n")

lmax= len(max(L,key=len))
L=[ np.concatenate((np.full(lmax-len(l),None),l))  for l in L ]
print(*L,"\n",sep="\n")

print(*zip(*L),"\n",sep="\n")

L= [ [ e for e in l if e] for l in zip(*L) ]
print(*L,"\n",sep="\n")

P= sorted([ p  for l in L for p in zip(l,l[1:]) ])
print(*P,"\n",sep="\n")

【讨论】:

  • 这在repetition = np.array([4, 2, 4, 2, 1, 1]) 的情况下不起作用。我相信在这种情况下正确的输出应该是:[(1, 7), (2, 8), (3, 5), (4, 6), (5, 9), (6, 10), (9, 11), (10, 12), (12, 13), (13, 14)].
  • @Pierre D 你是对的。我更正了上面的代码。
猜你喜欢
  • 2020-08-28
  • 1970-01-01
  • 1970-01-01
  • 2020-09-27
  • 1970-01-01
  • 2012-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多