熊猫数据框选择行,其中列表列包含任何字符串列表

时间:2018-11-16 17:29:34

标签: python pandas dataframe

我有一个看起来像这样的pandas DataFrame:

Problem<ISeq<ISeq<T>>, BitGene, Vec<double[]>>

并且我想提取一个DataFrame仅包含那些包含 molecule species 0 a [dog] 1 b [horse, pig] 2 c [cat, dog] 3 d [cat, horse, pig] 4 e [chicken, pig] 中任何一个的那些行。因此结果应如下所示:

selection = ['cat', 'dog']

最简单的方法是什么?

用于测试:

  molecule            species
0        a              [dog]
1        c         [cat, dog]
2        d  [cat, horse, pig]

6 个答案:

答案 0 :(得分:3)

IIUC重新创建df,然后将isinany一起使用应该比apply

df[pd.DataFrame(df.species.tolist()).isin(selection).any(1)]
Out[64]: 
  molecule            species
0        a              [dog]
2        c         [cat, dog]
3        d  [cat, horse, pig]

答案 1 :(得分:2)

您可以在此处将maskapply一起使用。

selection = ['cat', 'dog']

mask = df.species.apply(lambda x: any(item for item in selection if item in x))
df1 = df[mask]

对于上面作为示例提供的DataFrame,df1将为:

molecule    species
0   a   [dog]
2   c   [cat, dog]
3   d   [cat, horse, pig]

答案 2 :(得分:2)

在这种情况下,使用Numpy比使用Pandas快得多

选项1:使用numpy交集,

mask =  df.species.apply(lambda x: np.intersect1d(x, selection).size > 0)
df[mask]
450 µs ± 21.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

    molecule    species
0   a   [dog]
2   c   [cat, dog]
3   d   [cat, horse, pig]

选项2:与上述类似的解决方案,使用numpy in1d,

df[df.species.apply(lambda x: np.any(np.in1d(x, selection)))]
420 µs ± 17.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

选项3:有趣的是,在这里使用纯python设置非常快

df[df.species.apply(lambda x: bool(set(x) & set(selection)))]
305 µs ± 5.22 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

答案 3 :(得分:1)

这是一种简单且基本的方法。 您可以创建一个函数来检查“选择”列表中的元素是否存在于熊猫列列表中。

def check(speciesList):
    flag = False
    for animal in selection:
        if animal in speciesList:
            flag = True
    return flag

然后,您可以使用该列表基于记录是否包含“选择列表”中的至少一个元素来创建包含“ True of False”的列,并基于该元素创建新的数据框。

df['containsCatDog'] = df.species.apply(lambda animals: check(animals))
newDf = df[df.containsCatDog == True]

希望有帮助。

答案 4 :(得分:1)

user@host:/remote/directory

答案 5 :(得分:0)

使用熊猫frac = ['1/12', '1/6', ...] [eval(f) for f in frac] uses regular expression):

library(purrr)
Testdata %>% map_dbl(n_distinct)
var_1 var_2 var_3 
    1     1     3 

# in your format
Testdata %>% map_dbl(n_distinct)%>%melt(value.name = "unique_counts")
      unique_counts
var_1             1
var_2             1
var_3             3

输出:

str.contains