【问题标题】:Find common columns between Pandas and NumPy and extract column names查找 Pandas 和 NumPy 之间的公共列并提取列名
【发布时间】:2016-08-24 19:17:01
【问题描述】:

我在下面有一个 Pandas Dataframe (A) 和一个 NumPy 数组 (B)

A =
       M         N         C         D         E         F
0.882367  0.207342  0.959867  0.332126  0.031896  0.055734
0.640045  0.411328  0.794058  0.090374  0.629194  0.219321
0.423837  0.304872  0.370467  0.651361  0.017515  0.252440
0.865555  0.692180  0.790405  0.334760  0.863329  0.759971
0.843106  0.261376  0.385936  0.289840  0.063487  0.164913
0.881428  0.257026  0.139775  0.988289  0.953948  0.870969
0.862520  0.446840  0.754147  0.461149  0.607048  0.760438
0.839595  0.486050  0.012903  0.716871  0.155938  0.370666
0.663964  0.675242  0.066046  0.263634  0.242453  0.963562
0.761090  0.501848  0.896033  0.710318  0.581952  0.392896

B =
[[ 0.20734235  0.33212606  0.03189633]
 [ 0.41132799  0.09037417  0.6291936 ]
 [ 0.30487215  0.65136057  0.01751531]
 [ 0.69217974  0.3347596   0.86332925]
 [ 0.26137593  0.28984018  0.06348744]
 [ 0.25702646  0.98828911  0.95394809]
 [ 0.44684032  0.46114941  0.60704784]
 [ 0.4860496   0.71687057  0.15593771]
 [ 0.67524202  0.26363435  0.24245288]
 [ 0.50184753  0.71031779  0.58195151]]

A 的大小为 (10,6),B 的大小为 (10,3)。 NumPy 数组 B 中的列是 Pandas 数据框 A 中列的子集。不知道子集是怎么提前形成的。

如何在 Pandas 数据框 (A) 中找到也在 NumPy 数组 (B) 中的列的名称列表? 预期的输出应该是一个列表['N','D','E']

编辑:要在上面创建AB,此代码将起作用:

import numpy as np; import pandas as pd
A = pd.DataFrame(np.random.rand(10,6),columns=list('MNCDEF'))
y = A.iloc[:,[1,3,4]].values
B = y.view('float64')
B[:] = y

注意:使用此方法,您得到的数字将不会与我的数据相同。但是,就本示例而言,它应该足够了。

【问题讨论】:

    标签: python arrays python-2.7 numpy pandas


    【解决方案1】:

    您可以使用.duplicated() - 首先,使用pd.concat() 组合,然后选择匹配的列(当然可以使用df.columns 选择标题):

    B = pd.DataFrame(B)
    df = pd.concat([B, A], axis=1).T
    df[df.duplicated()].T
    
              N         D         E
    0  0.220376  0.275217  0.029644
    1  0.751950  0.170162  0.996459
    2  0.597565  0.440468  0.239183
    3  0.775364  0.476966  0.056998
    4  0.747164  0.654597  0.056527
    5  0.825209  0.699910  0.374902
    6  0.800624  0.837948  0.833588
    7  0.420070  0.102400  0.204857
    8  0.628885  0.345432  0.172771
    9  0.002239  0.868492  0.225563
    

    【讨论】:

    • 谢谢!这回答了我的问题。我实际上发现使用您的方法,甚至不需要最终的.T。我刚刚使用了duplicated()数据结构的索引:df[df.duplicated()].index.tolist()
    • 我接受了这个作为答案,但下面的帖子也适用于我在 OP 中的要求。
    【解决方案2】:
    for Bcol in B.T:
        cells = A.as_matrix() == Bcol.reshape(-1,1)
        cols = np.all(cells, axis=0)
        print A.columns[cols]
    

    【讨论】:

    • 非常感谢您的帖子。这与接受的答案一样有效 - 给了我正在寻找的列表。
    【解决方案3】:

    这是NumPy broadcasting 的矢量化方法-

    A.columns[np.where((A.values[...,None] == B[:,None]).all(0))[0]].tolist()
    

    基本上,A.values[...,None] 将所有现有维度推到前面。另一种说法是A.value[:,:,None]。所以,基本上我们将前两个维度推到前面,并在最后一个轴上创建一个单例维度,在进行比较时使用B[:,None] 进行广播。在这里,B[:,None] 本质上意味着B[:,None,:] 要明确说明它。其余代码检查沿第一个轴的所有匹配项,并将索引和索引获取到 A 的列名中以用于最终输出。


    如果您担心性能和内存效率,请允许我通过scipy's cdist 提出替代解决方案-

    from scipy.spatial.distance import cdist
    out = A.columns[np.where(cdist(A.values.T,B.T)==0)[0]].tolist()
    

    【讨论】:

    • 谢谢。这部分A.values[...,None]...指的是什么?
    • @WR 已将这些 cmets 添加到帖子中。
    【解决方案4】:

    numpy_indexed 包包含解决此类问题的功能;具体来说,npi.indices 函数:

    import numpy as np
    import numpy_indexed as npi
    import pandas as pd
    A = pd.DataFrame(np.random.rand(10,6),columns=list('MNCDEF'))
    B = A.as_matrix()[:, [1, 3, 4]]
    col_idx = npi.indices(A.as_matrix(), B, axis=1)  # gives back our [1, 3, 4] list
    print(list(A.index[col_idx]))
    

    也许这个解决方案可能更有效;不知道 pandas 对此操作的比较。

    【讨论】:

    • 哦,太好了!我以前从未使用过 numpy_indexed 。在最后一行,为什么需要A.dtypes.index 而不是A.index?我只是问,因为使用 A.index 似乎更直观,因为 A 是一个数据框。
    • 我越看这个,它就越像上面的pd.concat() 方法。就好像pd.concat() 后跟.duplicated() 的确切功能完全内置在numpy_indexed 中。如果我是对的,将这一切集中在一条线上真是太好了。
    • dtypes.index 就在那里,因为我是一个无知的熊猫;第一次点击我提取列名......我不确定它与引擎盖下的 pandas .duplicated() 相比如何;无论如何,就表达意图而言,我认为首先执行 concat 确实有点不雅。 id 说,npi.indices 是一个更普遍适用的功能。它只是 list.index 的矢量化等价物。
    【解决方案5】:

    inter_list = list((a_df.columns.values).intersection(set(b_df.columns.values)))

    inter_df = a_df[inter_list]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-15
      • 1970-01-01
      • 2015-05-31
      • 1970-01-01
      相关资源
      最近更新 更多