更快的方法,用于在列表中查找pandas列子集中的任何匹配值

时间:2018-03-10 18:39:05

标签: python pandas

我有一个非常非常大的数据框,类似于:

+---+--------+--------+--------+--------+
|   | code_1 | code_2 | code_3 | code_4 |
+---+--------+--------+--------+--------+
| 1 | abc    | def    | ghi    | jkl    |
| 2 | zzz    | zzz    | zzz    | zzz    |
| 3 | def    | zzz    | zzz    | zzz    |
| 4 | abc    | abc    | abc    | abc    |
| 5 | lol    | lol    | lol    | lol    |
+---+--------+--------+--------+--------+

我需要浏览每一行,并将设置的代码与一组经过批准的代码进行匹配。对于上面的示例,已批准的代码集为['abc', 'def']

如果给定行的任何与已批准的代码匹配,我希望返回True以添加到新列,否则返回False

鉴于上述批准的代码,输出如下:

+---+--------+--------+--------+--------+------------+
|   | code_1 | code_2 | code_3 | code_4 | is_primary |
+---+--------+--------+--------+--------+------------+
| 1 | abc    | def    | ghi    | jkl    | TRUE       |
| 2 | zzz    | zzz    | zzz    | zzz    | FALSE      |
| 3 | def    | zzz    | zzz    | zzz    | TRUE       |
| 4 | abc    | abc    | abc    | abc    | TRUE       |
| 5 | lol    | lol    | lol    | lol    | FALSE      |
+---+--------+--------+--------+--------+------------+

现在我执行此任务的方法如下:

def assign_primary(row, codes):
    is_primary = any(i in row.values for i in codes)

    if is_primary:
        return True
    return False

df['is_primary'] = df.apply(lambda row: assign_primary(
                            row, ['abc', 'def']), axis=1)

这可行,但在我的大数据集上速度非常慢。我将15个cols与100个超过200万行的100个批准代码列表进行匹配。

如果有人有这样做的方法,我正在寻找更快的实施。

1 个答案:

答案 0 :(得分:1)

list使用DataFrame.isin DataFrame.any进行检查,以检查每行至少一个True

print (df.isin(['abc', 'def']))
   code_1  code_2  code_3  code_4
1    True    True   False   False
2   False   False   False   False
3    True   False   False   False
4    True    True    True    True
5   False   False   False   False

df['is_primary'] = df.isin(['abc', 'def']).any(axis=1)
print (df)
  code_1 code_2 code_3 code_4  is_primary
1    abc    def    ghi    jkl        True
2    zzz    zzz    zzz    zzz       False
3    def    zzz    zzz    zzz        True
4    abc    abc    abc    abc        True
5    lol    lol    lol    lol       False

子集解决方案:

df['is_primary'] = df[['code_2','code_3']].isin(['abc', 'def']).any(axis=1)
print (df)
  code_1 code_2 code_3 code_4  is_primary
1    abc    def    ghi    jkl        True
2    zzz    zzz    zzz    zzz       False
3    def    zzz    zzz    zzz       False
4    abc    abc    abc    abc        True
5    lol    lol    lol    lol       False