所以我有两个 pandas 数据框,A 和 B。
A 是 1000 行 x 500 列,填充了指示存在或不存在的二进制值。
B 是 1024 行 x 10 列,并且是 0 和 1 的完整迭代,因此有 1024 行。
我正在尝试查找 A 中特定 10 列中的哪些行与 B 中的给定行相对应。我需要整行匹配,而不是逐个元素匹配。
例如,我想要
A[(A.ix[:,(1,2,3,4,5,6,7,8,9,10)==(1,0,1,0,1,0,0,1,0,0)).all(axis=1)]
要返回 A 中 (3,5,8,11,15)
行与 (1,0,1,0,1,0,0, 1,0,0)
B 在这些特定列的行 (1,2,3,4,5,6,7,8,9,10)
我想对 B 中的每一行都执行此操作。 我能想到的最好的方法是:
import numpy as np
for i in B:
B_array = np.array(i)
Matching_Rows = A[(A.ix[:,(1,2,3,4,5,6,7,8,9,10)] == B_array).all(axis=1)]
Matching_Rows_Index = Matching_Rows.index
这对一个实例来说并不可怕,但我在一个运行了大约 20,000 次的 while 循环中使用了它;因此,它会减慢速度。
我一直在摆弄 DataFrame.apply 无济于事。 map 可以更好地工作吗?
我只是希望有人看到明显更有效的东西,因为我对 python 还很陌生。
谢谢并致以最诚挚的问候!
最佳答案
我们可以滥用两个数据帧都有二进制值的事实 0
或 1
通过折叠来自 A
的相关列以及来自 B
的所有列进入1D
每个数组,当将每一行视为可以转换为十进制数等价物的二进制数序列时。这应该大大减少问题集,这将有助于提高性能。现在,在得到这些 1D
之后数组,我们可以使用 np.in1d
从 B
中查找匹配项在A
最后 np.where
在它上面得到匹配的索引。
因此,我们会有这样的实现 -
# Setup 1D arrays corresponding to selected cols from A and entire B
S = 2**np.arange(10)
A_ID = np.dot(A[range(1,11)],S)
B_ID = np.dot(B,S)
# Look for matches that exist from B_ID in A_ID, whose indices
# would be desired row indices that have matched from B
out_row_idx = np.where(np.in1d(A_ID,B_ID))[0]
sample 运行-
In [157]: # Setup dataframes A and B with rows 0, 4 in A having matches from B
...: A_arr = np.random.randint(0,2,(10,14))
...: B_arr = np.random.randint(0,2,(7,10))
...:
...: B_arr[2] = A_arr[4,1:11]
...: B_arr[4] = A_arr[4,1:11]
...: B_arr[5] = A_arr[0,1:11]
...:
...: A = pd.DataFrame(A_arr)
...: B = pd.DataFrame(B_arr)
...:
In [158]: S = 2**np.arange(10)
...: A_ID = np.dot(A[range(1,11)],S)
...: B_ID = np.dot(B,S)
...: out_row_idx = np.where(np.in1d(A_ID,B_ID))[0]
...:
In [159]: out_row_idx
Out[159]: array([0, 4])
关于python - 比较两个 Pandas 数据帧行的最快方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38267763/