例如:我们手头有>1百万行数据的销售表haha.csv,要筛选所有和客户,比如中国移动,有关的销售记录。怎么做?
- Python实现的关键点:在于使用
pandas.Series.str.contains
实现模糊匹配 ,即所有包含关键词“中国移动”在内记录。
第二版最新答案:
第一版答案用于遍历DataFrame是否含有关键词。但是,如果我们只需要查询一列数据是否含有目标关键词的话,如下更快捷:
# 第一种情况:筛选一个目标关键词
mask = df['目标列的名称'].str.contains('目标关键词')
selected_data = df[mask]
# 第二种情况:筛选n个目标关键词
List = ['key_w1', ..., 'key_wn']
mask = df['目标列的名称'].str.contains('|'.join(List))
selected_data = df[mask]
第一版答案:
从stackoverflow学来的答案;stackoverflow链接在此
import pandas as pd
def select_data():
df = pd.read_csv('路径+文件名.csv', encoding='gbk', low_memory=False)
mask = df.select_dtypes(include=[object]).stack().str.contains('中国移动').unstack() # 最快
# mask = df.select_dtypes(include=[object]).apply(lambda x: x.str.contains('中国移动', na=False))
# mask = df.select_dtypes(include=[object]).applymap(lambda x: '中国移动' in x if pd.notnull(x) else False) # 最慢
selected_data = df[mask.any(axis=1)]
selected_data.to_csv('路径+新文件名.csv', encoding='bgk)
if __name__ = '__main__':
select_data()
print('done')
重点代码节点分析:
df.select_dtypes(including=[object])
:返回全是str的部分(str的dtype
是object
);df.apply(function)
:apply a function along an axis of the DataFrame(将小括号里边的函数应用到定位出来的str部分);x.str.contains(i, na=False)
:na=False可以使得空值NaN的返回结果为False,而不是默认的NaN。df.any(axis=1)
:return whether any element is True over reguested axis。即“axis=1
”时,按行返回所有含有布尔值True的行。mask.any(axis=1)
:返回mask
里边包含True的行的Index。low_memory = Flase
:简单说是一个应该去掉但还没有去掉的一个参数。详细信息链接。
mask=部分
貌似在2百万条数据的时候很占内存。一个方法是:df.select_dtypes(incouding=[object]).apply(lambda x: x.str.contains('中国移动', na=False, regex=False, case=False)
mask 还等价于:
或df.apply ( lambda x: x.astype(str).str.contains(‘中国移动’).any(), axis=1 )
或df.apply ( lambda x: x.astype(str).str.contains(‘中国移动’) ).any(axis=1)
评价:由于把整个DataFrame数据转换为str,那么应用str.contains()的效率相对降低。
pandas.Series.str.contains()
官方文档这里。
Series.str.contains(
pat, # 要查询的字符串、要查询的或者正则表达式
case=True, # 是否对大小写敏感
flags=0, # 用来传给正则模块的参数,比如 flags=re.INGNORECASE 等价于 case=False
na=nan, # 默认对空值不处理,即输出结果还是 NaN
regex=True # 即第一个参数 pat部分 要不要按照正则表达式的规则。
#所以针对特殊符号,默认情况下我们必须使用转义符,或者设置 regex=False
)
由上可知,函数应用的必须是单列的str对象(str格式的Series,Index,Column都符合单列条件),返回的是模糊匹配的值,即False / True(唯一例外的是空值NaN:默认情况下返回的还是NaN)。
因此,函数应用对象是DataFrame时:一般先搭配select_dtypes(includeing=[object])
得到整列都是str格式的部分;再用.stack()
把N列(N>1)转换为单列,最后用.unstack()
还原为N列。