加快Pandas DB中的交叉引用过滤

时间:2016-07-22 17:30:06

标签: python performance pandas

我正在处理一个非常庞大的数据捐赠数据库,其中包含捐赠ID,管道ID,金额的相关列,例如:

  TRANSACTION_ID BACK_REFERENCE_TRAN_ID_NUMBER  CONTRIBUTION_AMOUNT
0    VR0P4H2SEZ1                             0                  100
1    VR0P4H3X770                             0                 2700
2    VR0P4GY6QV1                             0                  500
3    VR0P4H3X720                             0                 1700
4    VR0P4GYHHA0                  VR0P4GYHHA0E                  200

我需要做的是识别TRANSACTION_ID对应于任何BACK_REFERENCE_TRAN_ID_NUMBER的所有行。我目前的代码虽然有点笨拙但是:

is_from_conduit = df[df.BACK_REFERENCE_TRAN_ID_NUMBER != "0"].BACK_REFERENCE_TRAN_ID_NUMBER.tolist()
df['CONDUIT_FOR_OTHER_DONATION'] = 0
for row in df.index:
    if df['TRANSACTION_ID'][row] in is_from_conduit:
        df['CONDUIT_FOR_OTHER_DONATION'][row] = 1
    else:
        df['CONDUIT_FOR_OTHER_DONATION'][row] = 0

然而,对于拥有大量管道捐赠的非常大的数据集,这需要永远。我知道必须有一个更简单的方法,但显然我无法想出如何用这句话来找出可能的内容。

2 个答案:

答案 0 :(得分:5)

您可以使用Series.isin。它是一个向量化操作,用于检查Series的每个元素是否都在提供的可迭代中。

df['CONDUIT_FOR_OTHER_DONATION'] = df['TRANSACTION_ID'].isin(df['BACK_REFERENCE_TRAN_ID_NUMBER'].unique())

正如@root所提到的,如果您更喜欢0 / 1(如您的示例中)而不是True / False,则可以转为int

df['CONDUIT_FOR_OTHER_DONATION'] = df['TRANSACTION_ID'].isin(df['BACK_REFERENCE_TRAN_ID_NUMBER'].unique()).astype(int)

答案 1 :(得分:2)

以下是使用np.in1d -

的基于NumPy的方法
vals = np.in1d(df.TRANSACTION_ID,df.BACK_REFERENCE_TRAN_ID_NUMBER).astype(int)
df['CONDUIT_FOR_OTHER_DONATION'] = vals