Python Numpy:替换每行中特定索引后的行的剩余列

Python Numpy:替换每行中特定索引后的行的剩余列,python,numpy,Python,Numpy,我在一个三维数组中捕获了一些数据,这些数据的维度包括:时间刻度、样本数和每个样本的值数 通过前面的一个操作,我知道在某个时间点,是否每个样本号都无效。如果从未发生过这种情况,则将数字设置为-1。在其他情况下,它表示样本失效的时间刻度 我想做的是,要么将其余的列清空,要么将包含无效数据的列和右侧的列设置为NaN,要么使用某种屏蔽或索引技术,只将数据保留在左侧 我读过或找到过类似问题的参考资料,包括奇特的索引、slice()、布尔数组和掩码数组,但我没有找到实现我目标的方法 将numpy导入为np

我在一个三维数组中捕获了一些数据,这些数据的维度包括:时间刻度、样本数和每个样本的值数

通过前面的一个操作,我知道在某个时间点,是否每个样本号都无效。如果从未发生过这种情况,则将数字设置为-1。在其他情况下,它表示样本失效的时间刻度

我想做的是,要么将其余的列清空,要么将包含无效数据的列和右侧的列设置为NaN,要么使用某种屏蔽或索引技术,只将数据保留在左侧

我读过或找到过类似问题的参考资料,包括奇特的索引、
slice()
、布尔数组和掩码数组,但我没有找到实现我目标的方法

将numpy导入为np
#维度是时间步长、样本和每个样本的值。为了方便起见,让我们
#每个样本执行3个时间步、4个样本和2个值。
数据=np.数组([
[#时间步0
[1,2],#样本1
[ 3, 4 ],  #        2
[ 5, 6 ],  #        3
[ 7, 8 ],  #        4
],
[#时间步骤1
[ 1, 2 ], 
[ 3, 4 ],
[ 5, 6 ],
[ 7, 8 ],
],
[#时间步骤2
[ 1, 2 ], 
[ 3, 4 ],
[ 5, 6 ],
[ 7, 8 ],
],
])
每个样本可能在某个时间段失效。如果timestep从不无效,则值为-1

invalid_at = [ 
        0, # becomes invalid at timestep 0
        2, #                             2
        1, #                             1 
        -1 # Never is invalid
        ]
例如,如果我们用nan替换无效值,那么生成的数组应该如下所示

data = np.array( [
    [ # Timestep 0
        [ n, n ],  # Sample 1
        [ 3, 4 ],  #        2
        [ 5, 6 ],  #        3
        [ 7, 8 ],  #        4
    ],
    [ # Timestep 1
        [ n, n ], 
        [ 3, 4 ],
        [ n, n ],
        [ 7, 8 ],
    ],
    [ # Timestep 2
        [ n, n ], 
        [ n, n ],
        [ n, n ],
        [ 7, 8 ],
    ],
])
我遇到的主要困难是我有开始索引,但我找不到一种方法来创建一个切片(使用奇特的索引或其他方式),让我分配给它

例如,以下操作不起作用:

data[ :, invalid_at:-1, : ] = np.nan
我希望会发生的是,将对无效的at数组求值,并生成一个每行切片


我可以用for循环来实现这一点,但我更愿意保持它的矢量化,以提高速度和以后的可伸缩性。有什么想法吗?

有几种可能的方法可以做到这一点。主要的问题是,您试图应用的索引不完整

如果样本数很小,则可以在它们上循环,而额外开销相对较小。此选项非常简单,并支持简单切片索引,这通常是最快的索引类型,因为它不需要额外的数据副本或掩码:

for sample, step in enumerate(invalid_at):
    if step < 0:
        continue
    data[step:, sample, :] = np.nan

由于当前定义的整数to不支持NaN,因此仅当您显式设置
dtype=np.float
或类似的
data
时,此操作才有效。

采样数是否总是很小?例如,数百,甚至低千。它目前处于低千,但我预计它会增长。(顺便说一句,这是对我的实际问题的一般性解释,以一种希望可以理解的方式找到了问题的根源。)优化的“一般”解决方案的问题是优化,就其本质而言,是非常具体的案例。有太多的细节让我无法用一种普通观众都能理解的方式来表达我的全部问题。提出一个突出的最小工作示例正是我应该做的:o) 再次感谢,谢谢!这很有效。我想我可以将掩码切换为只接受trange@jrjbertram。在我看来,应用程序对于您的用例来说太具体了,解决方案也太琐碎了,无法讨论。不过,如果你自己有一个博客,那么在你这方面写一篇关于应用程序细节的文章是值得的。@jrjbertram。请不要编辑有重大修改的答案。因此,如果对未来的读者来说,如果不是更多的话,也同样是为了你的利益。在这种情况下,添加一个特定的示例并不能实质性地改进我的答案。因此提供了编辑功能。。。太好了。。。它可以使用。此外,为了每个人的利益,我扩展了答案,因为如果nan的写入数量很大,可能会有性能优势。它确实大大改进了答案,因为它提供了一个辅助实现替代方案。如果你不喜欢我做的,那很酷,我道歉。以您的答案为基础似乎比用替代实现来改变我的问题更合适。干杯,再次感谢。@jrjbertram。如果你觉得用一个基本上构成和答案的更新来编辑你的问题是不合适的,欢迎你发布你自己问题的答案。特别是如果执行情况客观上更好的话。如果你愿意,我会投你一票。
trange = np.arange(data.shape[0]).reshape(-1, 1)
srange = np.array(invalid_at).reshape(1, -1)
srange[srange == -1] = data.shape[0]
mask = (trange >= srange)
data[mask, :] = np.nan