猿问

如果满足条件,如何交换 Nx2 numpy 数组的行的元素?

my_array如果条件swap[i]是,我想将第 i 行的元素交换为 Nx2 numpy 数组True。


我的尝试:


def swap_positions_conditionally(my_array, swap):

    for i in range(np.shape(my_array)[0]):

        if swap[i]:

            my_array[i] = my_array[i][::-1]

    return my_array

工作正常,例如给定


my_array = array([[0, 1],

                  [2, 3],

                  [4, 5],

                  [6, 7],

                  [8, 9]])


swap = array([0, 0, 1, 1, 0])

产生预期的结果


[[0 1]

 [2 3]

 [5 4]

 [7 6]

 [8 9]]

但是,可能有一个更惯用的表达方式来重写我的swap_position_conditionally.

什么是更好(和更有效)的编写方式?


小怪兽爱吃肉
浏览 142回答 3
3回答

慕码人8056858

这是一个直接使用 Numpy 的布尔索引的方法:import numpy as npmy_array = np.asarray([[0, 1],                  [2, 3],                  [4, 5],                  [6, 7],                  [8, 9]])swap = np.array([0, 0, 1, 1, 0], dtype=bool)my_array[swap, :] = my_array[swap,:][:,(1,0)]分解关键线:my_array[swap, :] =表示“分配给swap正确的行”my_array[swap,:]意思是“选择正确的整行swap”[:,(1,0)]意思是“对于左边的每一行,交换第 0 列和第 1 列”关于问题的“更有效”部分......所有测试的通用设置(种子确保序列相同):import timeitsetup= '''import numpy as npnp.random.seed(42)my_array = np.random.random([10000,2])swap = np.random.random([10000]) > 0.5'''所有测试运行 1000 次迭代原码:5.621秒timeit.timeit('swap_positions_conditionally(my_array, swap)', setup=setup, number=1000)添加了 to 的定义,swap_positions_conditionally如setup问题所示。这个答案:0.2657 秒timeit.timeit('my_array[swap, :] = my_array[swap,:][:,(1,0)]', setup=setup, number=1000)Divakar 的回答:0.176 秒timeit.timeit('np.where(swap[:,None]!=1,my_array,my_array[:,::-1])', setup=setup, number=1000)亚图第一个答案:0.214秒timeit.timeit('np.take_along_axis(my_array, np.c_[swap, 1-swap], axis=1)', setup=setup, number=1000)亚图的第二个答案:0.2547秒timeit.timeit('my_array[swap,:] = my_array[swap,::-1]', setup=setup, number=1000)结论分析显示 Divakar 的版本是最快的。无论哪种更直观或更易读,都取决于口味,您可以选择您喜欢的一种(尽管我个人是索引符号可读性的粉丝......)

SMILET

这是一种交换Nx2数组并在您尝试时使用负步长切片翻转更多列的方法 -In [56]: np.where(swap[:,None]==1, my_array[:,::-1], my_array)Out[56]: array([[0, 1],       [2, 3],       [5, 4],       [7, 6],       [8, 9]])语法是:np.where(conditional_statement, choose_for_True, choose_for_False)。所以,在我们的例子中,我们想要在swapis时翻转/交换1,否则不要。需要该[:,None]部分在每一行中按元素执行此操作。如果swap已经是一个布尔数组,则跳过比较部分。

守着一只汪

这是一个使用np.take_along_axis:np.take_along_axis(my_array, np.c_[swap, 1-swap], axis=1)array([[0, 1],       [2, 3],       [5, 4],       [7, 6],       [8, 9]])或基于布尔索引:swap = swap.astype(bool)my_array[swap,:] = my_array[swap,::-1]
随时随地看视频慕课网APP

相关分类

Python
我要回答