pandas里applymap、apply、map、agg、groupby、自定义函数的使用

Pandas里三种调用函数应用的方法:
                 1:apply作用于DF的列或行
                 2:applymap作用于DF的所有元素
                 3:map作用于Series的所有元素
  agg函数很多情况下都是和groupby组合使用,通常指代分组聚合,它和apply的区别不是很明显,一般当调用自定义函数,没有聚合这个概念时最好使用apply。

  先上代码:核心代码是25、54、58行

# -*- coding:utf-8 -*-
from datetime import datetime
import pandas as pd
#*****************
##按天口径出的phone结果
# 口径:1)关键词且官网 2)关键词且app 3)关键词访问大于1 4)官网访问大于1
#*****************
def Main():
    dataList = '/data/u_lx_data/zhangqm/sh/yanjie/dudu/result_4G/list09.txt'
    # 对照表清单数据(加密和不加密手机号对应关系)
    mapRuletxt = '/data/u_lx_data/zhangqm/sh/yanjie/dudu/result_4G/mapRuletxt.txt'
    targetTxt = '/data/u_lx_data/zhangqm/sh/yanjie/dudu/result_4G/target2.txt'
    # 存储最终解果
    phoneSet = set()
    # 存储有关键词行为的phone
    kwPhoneSet = set()
    # 存储有官网行为的phone
    webPhoneSet = set()
    # app行为
    appPhoneSet = set()
    #存储对照表清单数据
    dict={}
    uname = ['phone', 'time', 'name']
    # 找官网的数据
    def web(str):
        if str.find('app') == -1 and str.find('kw') == -1:
            return str
    print("开始。。。。。")
    print(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))

    with open(mapRuletxt,'r') as fr:
        for line in fr:
            line = line.strip().split("\t")
            dict[line[1]] = line[0]
    with open(dataList,'r') as fr:
        for line in fr:
            line = line.strip().split("\t")
            if line[2].find('app') != -1: # app的
                appPhoneSet.add(line[0])
            elif line[2].find('kw') != -1: #关键词搜索的
                kwPhoneSet.add(line[0])
            else: # 官网访问行为的
                webPhoneSet.add(line[0])
    # 有过关键词搜索行为且有过官网访问行为的phone
    for kwphone in kwPhoneSet:
        if kwphone in webPhoneSet:
            phoneSet.add(kwphone)
    # 有过关键词搜索行为且有过app行为的phone
    for kwphone in kwPhoneSet:
        if kwphone in appPhoneSet:
            phoneSet.add(kwphone)
    # 关键词访问大于1的phone
    df = pd.read_table(dataList, sep="\t", header=None, names=uname, index_col=False)[['phone', 'name']]
    kw = df[df.name.str.contains('kw')].groupby('phone')['name'].agg([('uv',pd.Series.nunique)]).reset_index()
    for phone in  kw[kw.uv > 1]['phone']:
        phoneSet.add(phone)
    # 官网访问大于1的phone
    web = df.applymap(web).dropna().groupby('phone')['name'].agg([('uv',pd.Series.nunique)]).reset_index()
    for phone in  web[web.uv > 1]['phone']:
        phoneSet.add(phone)
    with open(targetTxt,'w+') as fw:
        for phone in phoneSet:
            if phone in dict:
                fw.write(dict[phone]+"\n")
    print("结束。。。。。")
    print(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
if __name__ == "__main__":
    Main()

df里的数据如图:
 
  
选出name列不包含app和kw的数据,经过代码df.applymap(web).dropna()就可以实现如图:

groupby和agg使用有一个注意点:
1:df[df.name.str.contains('kw')].groupby('phone')['name'].agg([('uv',pd.Series.nunique)])

2:df[df.name.str.contains('kw')].groupby('phone').agg([('name',pd.Series.nunique)])

其实1和2的最终结果是一样的,不一样的是结果对应的列名

当groupby之后跟指定的列agg函数里既可以写成自己需要的列名,如果不 跟指定的列agg函数里就必须写DF里的列名,不然会报不存在的列。

猜你喜欢

转载自blog.csdn.net/iboyman/article/details/80271047