查找Pandas和NumPy之间的公共列并提取列名称

时间:2016-04-29 14:55:47

标签: python arrays python-2.7 numpy pandas

我有一个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

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

5 个答案:

答案 0 :(得分:2)

您可以使用.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

答案 1 :(得分:1)

for Bcol in B.T:
    cells = A.as_matrix() == Bcol.reshape(-1,1)
    cols = np.all(cells, axis=0)
    print A.columns[cols]

答案 2 :(得分:1)

这是一个带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()

答案 3 :(得分:1)

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]))

也许这种解决方案可能更有效率;不知道熊猫如何比较这项行动。

答案 4 :(得分:0)

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

inter_df = a_df [inter_list]