【问题标题】:Remove column from numpy array according to columns in another array?根据另一个数组中的列从numpy数组中删除列?
【发布时间】:2020-01-16 16:24:19
【问题描述】:

我有一个 2d numpy 数组,叫它 C:

A = np.array([1,10,2])
B = np.array([4,-2,5])
C = np.vstack([A,B])

还有另一个 2d numpy 数组,称之为 G:

E = np.array([4,2,6])
F = np.array([0,5,30])
G = np.vstack([E,F])

如果 G 中的列与 C 中的列匹配,我想返回 1d 布尔值,所以在这种情况下

output = [False,True,False]

这里的第二个元素为真,因为(2,5)是G中的第二个元素,也匹配C中的第三个元素。

实际上,C 和 G 是包含约 300 万个元素的数组,但弄清楚这一点就足够了!

【问题讨论】:

    标签: python arrays numpy sorting indexing


    【解决方案1】:

    只是把我的熊猫想法也放在这里:

    import  pandas as pd
    
    dfc = pd.DataFrame(C).apply(tuple)
    dfg = pd.DataFrame(G).apply(tuple)
    
    print(dfg.isin(dfc))
    
    # 0    False
    # 1     True                                                
    # 2    False                                                  
    # dtype: bool                                      
    

    不过,对数百万个元素进行元组处理可能并不有趣...... :)

    【讨论】:

    • 感谢您将我的答案更改为已接受的答案。不过, 我会对原因感兴趣。我还没有测量性能,但是当@rafaelc 也提出了一种方法并且有意义地使用 numpy 经常击败其他算法时,我几乎无法想象得到最有效的答案。
    【解决方案2】:

    我相信这符合您对给定示例的需求。我对 numpy 还不够好,无法知道是否能很好地扩展到数百万条记录。

    import numpy as np
    
    A = np.array([1,10,2])
    B = np.array([4,-2,5])
    C = np.vstack([A,B]).T
    
    E = np.array([4,2,6])
    F = np.array([0,5,30])
    G = np.vstack([E,F]).T
    
    matches = [(C == g).any() for g in [g for g in G]]
    print(matches)
    

    【讨论】:

      【解决方案3】:

      您可以定义contiguous view 并使用np.in1d

      make_view = lambda a : np.ascontiguousarray(a.T).view([('', a.dtype)] * a.shape[0]).T.ravel()
      Cv, Gv = make_view(C), make_view(G)
      

      >>> np.in1d(Gv, Cv)
      array([False,  True, False])
      

      【讨论】:

        【解决方案4】:

        你没有提到你的列数,所以我假设它很小。

        C_r = np.repeat(C[:,:,np.newaxis],C.shape[1],axis=2)
        G_r = np.repeat(G[:,:,np.newaxis],G.shape[1],axis=2)
        G_r = np.transpose(G_r,(0,2,1))
        
        a = ~np.sum(G_r-C_r,axis=0).astype(bool)
        np.any(a,axis=0)
        Out[95]: array([False,  True, False])
        

        【讨论】:

          【解决方案5】:
          >>> g=G.transpose()
          >>> c=set(tuple(map(tuple, C.transpose())))
          >>> np.array([tuple(item) in c for item in g])
          
              array([False,  True, False])
          

          【讨论】:

          • 这行不通,因为它假定元素是独立的——它不是在搜索整个列。
          • 我认为应该是因为问题说“如果 G 中的列与 C 中的列匹配,则返回 1d 布尔值”
          • 你能提供任何会失败的 G 和 C 矩阵吗?
          • G中的0改成5,你会看到
          • @rafaelc 感谢您的指出。我已经更新了我的答案,与其他解决方案相比,它可能效率较低。
          猜你喜欢
          • 2011-03-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多