【问题标题】:filter tensorflow array with specific condition over numpy array在 numpy 数组上过滤具有特定条件的 tensorflow 数组
【发布时间】:2019-10-25 05:15:51
【问题描述】:

我有一个 tensorflow 数组名称 tf-array 和一个 numpy 数组名称 np_array。我想在tf_array 中找到与np-array 相关的特定行。

    tf-array = tf.constant(
                [[9.968594,  8.655439,  0.,        0.       ],
                 [0.,        8.3356,    0.,        8.8974   ],
                 [0.,        0.,        6.103182,  7.330564 ],
                 [6.609862,  0.,        3.0614321, 0.       ],
                 [9.497023,  0.,        3.8914037, 0.       ],
                 [0.,        8.457685,  8.602337,  0.       ],
                 [0.,        0.,        5.826657,  8.283971 ]])

我还有一个 np 数组:

np_array = np.matrix(
 [[2, 5, 1],
  [1, 6, 4],
  [0, 0, 0],
  [2, 3, 6],
  [4, 2, 4]]

现在我想保留tf-array 中的元素,其中n (here n is 2) 的组合(它们的索引)在np-array 的值中。什么意思?

例如,tf-array 中,第一列中具有值的索引为:(0,3,4)np-array 中是否有任何行包含这两个索引的任意组合:(0,3), (0,4) or (3,4)。实际上,没有这样的行。所以该列中的所有元素都变成了zero

tf-array 中第二列的索引是 (0,1) (0,5) (1,5)。如您所见,记录 (1,5) 在第一行的np-array 中可用。这就是我们将这些保留在tf-array 中的原因。

所以最终的结果应该是这样的:

[[0.        0.        0.        0.       ]
 [0.        8.3356    0.        8.8974   ]
 [0.        0.        6.103182  7.330564 ]
 [0.        0.        3.0614321 0.       ]
 [0.        0.        3.8914037 0.       ]
 [0.        8.457685  8.602337  0.       ]
 [0.        0.        5.826657  8.283971 ]]

我正在寻找一种非常有效的方法,因为我有大量数据。

更新1

我可以用下面的代码得到这个,它给出了True,其中有值和零掩码给false

[[ True  True False False]
 [False  True False  True]
 [False False  True  True]
 [ True False  True False]
 [ True False  True False]
 [False  True  True False]
 [False False  True  True]]

with tf.Session() as sess:  
 where = tf.not_equal(tf-array, 0.0)
 print(sess.run(where))

但是如何将这些矩阵与np_array 进行比较?

提前谢谢你!

【问题讨论】:

    标签: python arrays numpy tensorflow slice


    【解决方案1】:

    这是来自https://stackoverflow.com/a/56510832/7207392 的解决方案,并进行了必要的修改。为简单起见,我对所有数据使用np.array。我不是 tensorflow 专家,所以如果翻译不完全直截了当,你就得问别人怎么做。

    import numpy as np
    
    def f(a1, a2, n):
        N,M = a1.shape
        a1p = np.concatenate([a1,np.zeros((1,a1.shape[1]),a1.dtype)], axis=0)
        a2 = np.sort(a2, axis=1)
        a2[:,1:][a2[:,1:]==a2[:,:-1]] = N
        y,x = np.where(np.count_nonzero(a1p[a2], axis=1) >= n)
        out = np.zeros_like(a1p)
        out[a2[y],x[:,None]] = a1p[a2[y],x[:,None]]
        return out[:-1]
    
    a1 = np.array(
        [[9.968594,  8.655439,  0.,        0.       ],
         [0.,        8.3356,    0.,        8.8974   ],
         [0.,        0.,        6.103182,  7.330564 ],
         [6.609862,  0.,        3.0614321, 0.       ],
         [9.497023,  0.,        3.8914037, 0.       ],
         [0.,        8.457685,  8.602337,  0.       ],
         [0.,        0.,        5.826657,  8.283971 ]])
    
    a2 = np.array(
     [[2, 5, 1],
      [1, 6, 4],
      [0, 0, 0],
      [2, 3, 6],
      [4, 2, 4]])
    
    print(f(a1,a2,2))
    

    输出:

    [[0.        0.        0.        0.       ]
     [0.        8.3356    0.        8.8974   ]
     [0.        0.        6.103182  7.330564 ]
     [0.        0.        3.0614321 0.       ]
     [0.        0.        3.8914037 0.       ]
     [0.        8.457685  8.602337  0.       ]
     [0.        0.        5.826657  8.283971 ]]
    

    【讨论】:

    • 非常感谢您的帮助,我正在尝试将其转换为 tensorflow 方式
    【解决方案2】:

    您可以尝试的一种有效方法是为每一行制作位标志, (0,3,4) 的值是 1

    这种悬停不适用于浮点数 - 您需要将它们转换为非常小的整数。

    import numpy as np
    
    
    
    arr_one =  np.array(
     [[2, 5, 1],
      [1, 6, 4],
      [0, 0, 0],
      [2, 3, 6],
      [4, 2, 4]])
    
    arr_two =  np.array(
     [[2, 0, 7],
      [1, 3, 4],
      [5, 5, 6],
      [1, 3, 6],
      [4, 2, 4]])
    
    
    
    
    print('1 << arr_one.T[0] ' , 1 << arr_one.T[0] )
    
    
    arr_one_flags = 1 << arr_one.T[0] | 1 << arr_one.T[1] | 1 << arr_one.T[2]
    
    print('arr_one_flags ', arr_one_flags)
    
    arr_two_flags = 1 << arr_two.T[0] | 1 << arr_two.T[1] | 1 << arr_two.T[2]
    
    arr_and = arr_one_flags & arr_two_flags
    
    print('arr_and ', arr_and)
    
    
    
    def get_bit_count(value):
        n = 0
        while value:
            n += 1
            value &= value-1
        return n
    
    arr_matches = np.array([get_bit_count(x) for x in arr_and])
    
    
    print('arr_matches ', arr_matches )
    
    
    arr_two_filtered = arr_two[arr_matches > 1]
    
    print('arr_two_filtered ', arr_two_filtered )
    

    【讨论】:

    • 感谢您跟进我的问题,尽管您的建议有点含糊。你能给我一个你想法的最小工作代码吗?另外,不幸的是我无法将 float 更改为 int
    • 享受吧。像 int(f*1000) 一样更改浮点数,否则您无法设置标志,这将降低效率
    • 非常感谢您花时间,我无法将 float 更改为 int,因为它们是 nn 的重量,根本无法更改。你能提供更多关于效率较低的方法“设置标志,这将降低效率”的线索吗?
    • 实际上是神经网络中我想要更改的层之一中的矩阵,这就是为什么我无法更改 tf-array 中的权重值。
    猜你喜欢
    • 2023-03-04
    • 2021-04-08
    • 1970-01-01
    • 1970-01-01
    • 2018-06-06
    • 2019-01-31
    • 2019-10-23
    • 1970-01-01
    • 2021-07-05
    相关资源
    最近更新 更多