检查一个单元格的值是否在另一个单元格的列表/集中

时间:2018-08-17 18:14:06

标签: pandas vectorization

如果我具有以下DataFrame:

      country       countries
1      France       {France, Sweden, England}
2     Germany       {France, Sweden, England}
3     Germany       {Portugal, Greece, Germany}
4      Sweden       {Spain, England}
5       Spain       {England, Greece}
6       Spain       {Portugal, Spain, Italy}

是否有一种快速(矢量化)检查country是否在countries集中的方法?

      country       countries                         is_in
1      France       {France, Sweden, England}         True
2     Germany       {France, Sweden, England}         False
3     Germany       {Portugal, Greece, Germany}       True
4      Sweden       {Spain, England}                  False
5       Spain       {England, Greece}                 False
6       Spain       {Portugal, Spain, Italy}          True

使用df.apply()做到这一点非常容易,但也非常慢。因此,我正在寻找使用Numpy或本地Pandas向量化方法的解决方案。

我想到了Numpy的np.isin()np.in1d(),但它们不合适,因为它们假定要比较的唯一,恒定的一组值,而不是每行一组。

3 个答案:

答案 0 :(得分:2)

IIUC

[x in y for x , y in zip(df.country,df.countries)]

答案 1 :(得分:1)

您可以使用设置交集

df.country.transform(lambda s: {s}) & df.countries.values

检查时间

df = pd.concat([df]*1000)

%timeit df.country.transform(lambda s: {s}) & df.countries.values
4.53 ms ± 512 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit df.apply(lambda x: x['country'] in x['countries'], 1)
156 ms ± 6.25 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit [x in y for x , y in zip(df.country,df.countries)]
598 µs ± 97.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

答案 2 :(得分:0)

如果您可以将花括号更改为方形花括号,则可以使用df.iterrows()

df["is_in"] = [row["country"] in row["countries"] for idx, row in df.iterrows()]

我不知道这是否满足您的时间限制,但希望对您有所帮助。