python: 进阶 - 数据预处理 - 数据提取 - 使用str.contains()实现EXCEL的模糊匹配筛选功能

例如:我们手头有>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_dtype(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')

重点代码节点分析:

  1. df.select_dtypes(including=[object]):返回全是str的部分(str的dtypeobject);
  2. df.apply(function):apply a function along an axis of the DataFrame(将小括号里边的函数应用到定位出来的str部分);
  3. x.str.contains(i, na=False):na=False可以使得空值NaN的返回结果为False,而不是默认的NaN。
  4. df.any(axis=1):return whether any element is True over reguested axis。即“axis=1”时,按行返回所有含有布尔值True的行。
  5. mask.any(axis=1):返回 mask里边包含TrueIndex
  6. low_memory = Flase:简单说是一个应该去掉但还没有去掉的一个参数。详细信息链接。

mask=部分貌似在2百万条数据的时候很占内存。一个方法是:df.select_dtype(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_dtype(includeing=[object])得到整列都是str格式的部分;再用.stack()N列(N>1)转换为单列,最后用.unstack()还原为N列


你可能感兴趣的:(python:数据预处理)