【发布时间】:2022-01-19 03:04:32
【问题描述】:
我有一个 2D NumPy 数组,专门用 1 和 0 填充。
a = [[0 0 0 0 1 0 0 0 1]
[1 1 1 1 1 1 1 1 1]
[1 1 1 1 1 1 1 1 1]
[1 1 1 1 0 0 0 0 1]
[1 1 1 1 1 1 1 1 1]
[1 1 1 0 1 1 1 1 1]
[1 1 1 1 1 1 0 0 1]
[1 1 1 1 1 1 1 1 1]]
为了获取 0 的位置,我使用了以下代码:
new_array = np.transpose(np.nonzero(a==0))
正如预期的那样,我得到以下结果,显示了数组中 0 的位置
new_array = [[0 0]
[0 1]
[0 2]
[0 3]
[0 5]
[0 6]
[0 7]
[3 4]
[3 5]
[3 6]
[3 7]
[5 3]
[6 6]
[6 7]]
现在我的问题来了: 如果所述组大于2,有没有办法在水平组的开始和结束处获取0的位置?
编辑:如果组要在一行的末尾完成并继续在它下面的一个,它将计为 2 个单独的组。
我的第一个想法是实现一个过程,如果它们位于 0 之间,将删除 0,但我无法弄清楚如何做到这一点。
我希望“new_array”输出为:
new_array = [[0 0]
[0 3]
[0 5]
[0 7]
[3 4]
[3 7]
[5 3]
[6 6]
[6 7]]
先谢谢了!!
编辑 2:
感谢大家提供的非常有用的见解,我能够解决我遇到的问题。
为了满足好奇心,这些数据代表音乐信息。我正在开发的程序的目的是根据图像(仅由水平线组成)创建乐谱。
图像到 1 和 0 的转换完成后,我需要从中提取以下信息:Onset、Pitch 和 Duration。这转化为“x”轴上的位置、“y”轴上的位置和组的总长度。
由于 X 和 Y 位置相当容易获得,因此我决定将它们与“持续时间”计算分开处理(这是本文要解决的主要问题)。
感谢您的帮助,我能够解决 Duration 问题并创建一个包含所有必要信息的新数组:
[[0 0 4]
[5 0 3]
[4 3 4]
[6 6 2]]
请注意,第 1 列代表 Onset,第 2 列代表 Pitch,第 3 列代表 Duration。
我还注意到建议为每个事件添加标识符的评论。最终我需要实现它以区分不同的乐器(然后将它们发送到单独的 Midi 通道)。但是,对于仅旨在为单个乐器创建乐谱的程序的第一次迭代,这不是必需的,因为所有事件都属于单个乐器。
我对编程的经验很少,我不知道这是否是实现我目标的最有效方式。欢迎提出任何建议。
谢谢!
【问题讨论】:
-
真的想要一个交替运行开始和结束的一维序列吗?元组序列或宽度为 2 的数组不是更有意义吗?另外,如果一次跑步在一行结束时结束,并在下一行继续,那是一次跑步,还是两次跑步?
-
您需要避免在
numpy中进行类似for的迭代,因为它们很慢。请改用np.transpose(np.nonzero(a==0)) -
@Grismar 实际上,如提供的示例所示,我希望“new_array”的宽度为 2,显示运行的开始和结束,如果它们运行的长度大于2. 对于您问题的第二部分,出于数据的目的,它将计为两次单独的运行。
-
FWIW:我对您提出的输出感到担忧。它无法正确区分单次运行和较长时间的运行。考虑
[0 1 0 1]与[0 0 0 1]。它们都将在您的最终表示中产生[[0 0] [0 2]]。最好表示为开始位置和运行次数。我可能将第一个表示为[[0 0 1] [0 2 1]],将第二个表示为[[0 0 3]]。尽管我可能不会将其保留为 numpy 格式;相反会做[[0 0], 3]或者[0, 0], 3]。我的意思是,在那个阶段我会编写普通的 Python 代码来操作简单的对象。 -
@I-like-weird-sounds 道歉,我的澄清问题措辞不佳-我认为
(5, 2, 2)的形状数组更有意义[[[0 0][0 3]][[0 5][0 7]][[3 4][3 7]][[5 3][5 3]][[6 6][6 7]]],尤其是因为在您的格式中建议,不清楚[5 3][6 6]是否是一个区间,或者[5 3]应该被解释为单个0- 你只能判断你是否回到原始数据。
标签: python arrays numpy conditional-statements