更快的方式.isin()提取条件行

时间:2017-07-09 20:18:13

标签: pandas dataframe

我编写的代码可以查找所有'联系人' (通过名称分组)通过电子邮件完成。然后,使用.isin()完成,提取True布尔值以创建新的数据帧。 是否有更快捷,更简单的方法?

df = pd.DataFrame({'Name':['adam','ben','ben','ben','adam','adam','adam'],
                   'Date':['2014-06-01 18:47:05.069722','2014-06-01 18:47:05.069722','2014-06-30 13:47:05.069722',
                      '2013-06-01 18:47:05.069722','2014-01-01 18:47:05.06972','2014-06-01 18:47:05.06972',
                      '2014-06-02 18:47:05.06972'], 
                   'Contact':['phone','email','email','email','email','email','Nan']})

"""只提取那些联系方式为'电子邮件'的行,以构建新的数据框"""

 emails = df.groupby('Name')['Contact'].apply(lambda i: i.isin(['email']))
 a = list(np.where(email))  #create list of indices of True booleans 
 lst = a[0]
 df = df.iloc[lst, :] #new dataframe

2 个答案:

答案 0 :(得分:1)

您实际上可以将此与locboolean indexing

一起使用
df = df.loc[df.Contact == "email"]
使用str.replace

甚至更快一点如下:@Sergey Bushmanov提到

df = df.loc[df.Contact.str.contains("email")]
如果您使用大量数据并且我相信丢失的更简单,那么

会提供完全相同的输出,速度会更快。

Vectorized方法总是比apply快。

您还可以参考此link以获取有关pandas方法的速度和性能的更多信息。

有关enhancing performance的其他文档。

答案 1 :(得分:1)

为了完整起见:

df = df.loc[df.Contact.str.contains("email")]

运行时:

%timeit df.loc[df.Contact.str.contains("email")]
646 µs ± 20 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit df.loc[df.Contact == "email"]
750 µs ± 19.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

PS

用于str操作的

string方法通常针对处理文本进行了优化。对于大型DF来说,时差会更大。