IF函数详解,ExcelPythonSQLTableau四个工具同时登场 IF函数是Excel中最常用的函数之一,它可以对值进行逻辑比较。这个函数的语法非常符合人类语言, 如果就否则 比如说如果你喜欢我,我们就结婚,否则就不结婚 用IF来实现就是IF(youloveme,wearemarried,wearen’tmarried) 使用逻辑函数IF函数时,如果条件为真,该函数将返回一个值;如果条件为假,函数将返回另一个值。 第一个参数是条件真假值,第二个参数是条件为真时的返回值,第三个参数是条件为假时的返回值 这个函数还可以写成无限嵌套模式(俗称套娃),IF(IF(IF(IF,,但是个人不建议这样写,因为这种写法实在是太容易给自己弄迷糊,如果是多条件判断,可以考虑IFS,如果只是取值判断建议写成IF()IF()IF()单IF函数相加这种形式完成 本例主要解决以下问题: 1如果成绩大于等于600分,则返回优秀,否则返回普通 2如果成绩大于等于600分,则返回优秀,大于等于500分小于600分返回普通,小于500分返回不优秀 3如果成绩大于600分并且性别为男,则返回男优秀,如果成绩大于600分且性别为女,返回女优秀,否则返回不优秀 4如果语文成绩大于120分,或者数学成绩大于120分,则返回单科优秀,否则返回普通 5花名册里技能字段如果包含剑字则返回剑法,如果包含刀字,则返回刀法,除此之外返回其他 6从字符串里提取指定位置的文本,本例从地址列文本里面进行提取省名、市名、县名 实现方式:Excel、Python、SQL、Tableau Excel实现 1如果成绩大于等于600分,则返回优秀,否则返回普通 在J2单元格输入公式:IF(I2600,优秀,普通) 2如果成绩大于等于600分,则返回优秀,大于等于500分小于600分返回普通,小于500分返回不优秀 在J2单元格输入公式:IF(I2600,优秀,IF(I2500,普通,不优秀)) 说明:此时一共有两个IF函数,里面嵌套了一个,这个语句先判断第一个IF,如果大于等于600,则返回优秀,然后把剩下的小于600的单元格区域丢给第二个IF函数判断,因为此时这里面都是小于600分的单元格了,所以只需要在判断条件处写大于等于500即可,没必要再加小于600分的条件,然后进行判断,把里面500分及以上的返回普通,剩下的丢给后面,如果还有IF的话就再继续判断,没有的话,则统一返回最后一个IF函数里面的第三个参数,这里也就是不优秀,如果不用嵌套,改用IFS函数如何实现本例呢? 改用IFS函数实现,在J2单元格输入公式:IFS(I2600,优秀,I2500,普通,I2500,不优秀) 用法:IFS(〔SomethingisTrue1,ValueifTrue1,SomethingisTrue2,ValueifTrue2,SomethingisTrue3,ValueifTrue3) 这里面最少要有两个参数,第一个参数是判断条件,第二个参数是返回值,最多可以判断127个条件,也就是254个参数,和SUM求和的参数极限类似 IFS函数检查是否满足一个或多个条件,且返回符合第一个TRUE条件的值,判断时是按顺序依次进行,这个函数可以取代多个嵌套IF语句,并且有多个条件时更方便阅读 如果找不到TRUE条件,则此函数返回NA!错误,例如只输入一个大于600分的条件判断:IFS(I2600,优秀) 这时小于600分的部分会返回NA,也就是查不到 此时我们需要前面加一个IFERROR进行修复一下,比如小于600分的返回普通,输入公式:IFERROR(IFS(I2600,优秀),普通) IFERROR用法说明:IFERROR(value,valueiferror) 第一个参数是正常返回的值,当第一个参数无法返回值时返回第二个参数作为结果 还有一个函数IFNA(),用法基本和这个一样 这里相当于用了一个复合函数,首先IFS(I3600,优秀)作为IFERROR函数的第一个参数,这里可以完成大于等于600分以上条件的返回,这个参数IFERROR并不理会,而只有当这个条件不能返回时,即前面所说的查不到的NA部分,IFERROR函数会自动把这一部分的单元格返回第二个参数,这里面也就是返回普通 3如果成绩大于600分并且性别为男,则返回男优秀,如果成绩大于600分且性别为女,返回女优秀,否则返回不优秀 输入公式IFERROR(IFS(AND(B11男,I11600),男优秀,AND(B11女,I11600),女优秀),普通) 说明:AND和OR函数 AND是且判断,都为真时为真,只要有一个为假则为假,AND(11,22,33,44)为真,AND(11,22,33,45)为假 OR是或判断,都为假时为假,只要有一个为真则为真,OR(12,34,56,78)为假,OR(12,34,56,77)为真 这两个一般都需要配合前面的IF函数进行使用,应该很少有单独使用场景 4如果语文成绩大于120分,或者数学成绩大于120分,则返回单科优秀,否则返回普通 输入公式:IF(OR(E2120,F2120),单科优秀,普通) 5花名册里技能字段如果包含剑字则返回剑法,如果包含刀字,则返回刀法,除此之外返回其他 输入公式:IFERROR(IFS(ISNUMBER(FIND(剑,E2)),剑法,ISNUMBER(FIND(刀,E2)),刀法),其他) IS类函数返回逻辑值:ISNUMBER搭配FIND函数使用,可以对指定单元格以判断是否存在关键字词进行对应返回 类似的函数还有以下: FIND用法说明:FIND(findtext,withintext,〔startnum〕) 第一个参数是要查找的关键字,这里我们输入的是剑或者刀,此参数严格区分大小写,并且不允许使用通配符 第二个参数是要在哪个文本里查找,我们这里在技能列查找,比如田伯光的技能狂风刀法 第三个参数可选,是从第几个开始查询,默认为1 拆解公式:FIND(刀,狂风刀法,1)这个公式返回的是一个数字3,也就是说刀字在这个单元格字符里面的第3位,只要能返回数字不管在第几位,也就意味着这个单元格里包含有我们要查找的关键字 然后我们再用ISNUMBER函数把这个数字3转化为逻辑值真,为IFS函数提供参数用 ISNUMBER(FIND(刀,狂风刀法,1))返回值为TRUE 我们可以看到除了田伯光技能’狂风刀法‘里面含有刀字,返回的是刀法,其他大多为剑法 这个函数用处场景较多,之前我曾见过某同事在处理大量数据时,用筛选包含关键字的形式一次一次地手动输入返回值,如果能用这个函数则会极大提高数据处理效率 6从字符串里提取指定位置的文本,本例从地址列文本里面进行提取省名、市名、县名 FIND查找函数配合字符提取函数LEFT,RIGHT,MID等,可以实现强大的字符提取功能: 从以下字符串中提取省名,MID(A1,1,FIND(省,A1)) 我们发现如果用LEFT进行向左直接取数字几位的话无法实现,因为有的省是两个字,有的是三个字,这时我们就需要借助FIND对每一行的省名有几个字符进行判断 FIND(省,A1))返回值显示包括省字在内的省名个数,比如前面两条返回的是3,黑龙江的返回的为4 MID用法:MID(text,startnum,numchars) 第一个参数表示,要从哪个字符串里提取,这里我们取A列 第二个参数表示,从第几个字符开始提取,这里我们填1,表示从头进行提取 第三个参数表示,提取多少个字符,这里正是FIND函数起作用的地方 如前,假如提取省名不包括省字本身,则只需要在第三个参数后面减1即可,也就是提取字符少一位 MID(A1,1,FIND(省,A1)1) 这里我们也可以使用LEFT函数,LEFT(A1,FIND(省,A1)) LEFT函数只有两个参数,第一个是要提取的单元格,第二个是提取的位数,从左 同理:RIGHT函数两个参数,第一个是要提取的单元格,第二个是提取的位数,从右 如果把大庆市改为齐齐哈尔市,这回我们提取后面的市名,公式:MID(A1,FIND(省,A1)1,10) 这里FIND函数传递的值是作为MID函数的第二个参数,也就是从第几位开始提取,FIND(省,A1)1表示出现省字后面第一个字符的位数,第三个参数可以写一个比较大的数字,只要提取的位数小于这个数值,则默认全部提取到最后 还可以用RIGHT提取:RIGHT(A1,LEN(A1)FIND(省,A1)) 这里RIGHT的第二个参数是用了计算得来了,省名的位数FIND(省,A1),LEN(A1)表示全部的位数,两者相减得到的则是要提取的市名的位数 还可以再升级,后面加上县名等,我们从中间提取市名MID(A1,FIND(省,A1)1,FIND(市,A1)FIND(省,A1)) 说明: FIND(省,A1)1表示市名第一个文本出现在第几位上 FIND(市,A1)FIND(省,A1)表示市名文本的字符长度,例如第一个,FIND(市,A1)6表示市字出现在第6位,FIND(省,A1)3,省字出现在第三位,两者的差633则是铁岭市的字符长度Python实现: 1如果成绩大于等于600分,则返回优秀,否则返回普通 代码如下: defscoreif(score): ifscore600: a优秀 else: a普通 returna df〔是否优秀〕df〔总成绩〕。apply(lambdax:scoreif(x)) 这种我们是用lambda表达式实现: 前面自定义一个函数,scoreif进行逻辑判断取数 df〔是否优秀〕df〔总成绩〕。apply(lambdax:scoreif(x)) 这条语句相当于把总成绩那列应用到函数scoreif,然后把返回值赋给是否优秀列 附:本例还可以用一行代码完成,使用lambda匿名函数,这是一种没有名称的函数 df〔是否优秀〕df〔总成绩〕。apply(lambdax:优秀ifx600else普通) 2如果成绩大于等于600分,则返回优秀,大于等于500分小于600分返回普通,小于500分返回不优秀 代码如下: defscoreif(score): ifscore600: a优秀 elifscore500: a普通 else: a不优秀 returna df〔是否优秀〕df〔总成绩〕。apply(lambdax:scoreif(x)) 这里第9行代码也可以写成这样df〔是否优秀〕df〔总成绩〕。apply(scoreif) appy是应用的意思,这行表示把总成绩列作为scoreif函数的参数,然后函数返回值赋给是否优秀列 如果用lambda函数,一行代码: df〔是否优秀〕df〔总成绩〕。apply(lambdax:优秀ifx600else(普通ifx500else不优秀)) 3如果成绩大于600分并且性别为男,则返回男优秀,如果成绩大于600分且性别为女,返回女优秀,否则返回不优秀 代码如下: defscoreif(score,sex): ifscore600andsex男: a男优秀 elifscore600andsex女: a女优秀 else: a普通 returna dfpd。readexcel(c:studynotexiaoif。xlsx,sheetname成绩单) df〔是否优秀〕df。apply(lambdadf:scoreif(df〔总成绩〕,df〔性别〕),axis1) 附:还有一种写法如下 defscoreif(score,sex): ifscore600andsex男: a男优秀 elifscore600andsex女: a女优秀 else: a普通 returna dfpd。readexcel(c:studynotexiaoif。xlsx,sheetname成绩单) df〔是否优秀〕None foriinrange(len(df)): df〔是否优秀〕〔i〕scoreif(df〔总成绩〕〔i〕,df〔性别〕〔i〕) 这里用到了条件且在自定义函数里面,因为自定义函数有两个参数,我再后面用了一个for循环语句 第10行:新建一个字段,命名为‘是否优秀’ 第11行,让变量i进行循环,len(df)表示原表的行数,等于18,range(18)相当于让i从0取到17 第12行,把每一行的总成绩列值作为函数的第一个参数,性别列值作为第二个参数,然后把返回值赋给是否优秀列,因为i是变量,从0到17(意义表示从第1行到第18行) 在python中and和or函数,布尔类型也是只有True和False两种取值,python中的布尔运算符and,or,not全是小写 逻辑运算和Excel一样 但是当用pandas库的数据类型DataFrame和Series时进行逻辑运算时,此时运算符变成 表示and且 表示or或 表示not非 4如果语文成绩大于120分,或者数学成绩大于120分,则返回单科优秀,否则返回普通 代码: defscoreif(chi,math): ifchi120ormath120: a单科优秀 else: a普通 returna dfpd。readexcel(c:studynotexiaoif。xlsx,sheetname成绩单) df〔是否优秀〕df。apply(lambdadf:scoreif(df〔语文〕,df〔数学〕),axis1) 5花名册里技能字段如果包含剑字则返回剑法,如果包含刀字,则返回刀法,除此之外返回其他 代码如下: dfpd。readexcel(c:studynotexiaoif。xlsx,sheetname花名册) colnamedf。columns。tolist() colname。insert(colname。index(技能)1,技能类型) dfdf。reindex(columnscolname) deftech(x): ifx。find(剑)0: a剑法 elifx。find(刀)0: a刀法 else: a其他 returna df〔技能类型〕df〔技能〕。apply(tech) 第3行:把原表所有列名转换为列表格式,并传递给变量colname 第4行:在列名列表里‘技能’文本后面新插入一个文本‘技能类型’,作为一个新的字段列名 第5行:把新增加的字段传递给原表df 第6行:x。find(参数),表示在x单元格查找参数所有的位置,如果单元格里存在参数,则返回位置数字,如果不存在则返回1,如果参数在单元格第1位,则返回0,因为在python里顺序是从0开始,0代表第一位,x。find(剑)0表示单元格值里面存在剑这个关键词,相当于Excel时面函数ISNUMBER(FIND(剑,独孤九剑,1))返回值为TRUE一样 6从字符串里提取指定位置的文本,本例从地址列文本里面进行提取省名、市名、县名 代码如下: df〔省〕df〔地址〕。apply(lambdax:x〔0:x。find(省)1〕) df〔市〕df〔地址〕。apply(lambdax:x〔x。find(省)1:x。find(市)1〕) df〔县〕df〔地址〕。apply(lambdax:x〔x。find(市)1:〕) 这里直接用了python里面的切片(slicing)语法:sequence〔start:stop:step〕 sequence是序列的意思,第一个参数是起始位置,第二个参数是结束位置(不包括本身,相当于数学里面的左闭右开区间),第三个参数是步长,举例:a辽宁省铁岭市昌图县八面城镇在本例中文本值作为一个序列 a〔0:3〕表示:从第1位开始取3位(0,1,2) a〔:3〕表示:和上面一样,只是省略了第1个参数 a〔::〕表示全取,三个参数都省略了 a〔4:〕表示从右边第三位开始向右取数取到最后 a〔::2〕表示每两个元素取一个 a〔1:5:1〕表示从右往左取4位,这里面第二个参数和第三个参数都是负数,第二个参数相当于从右往左数第5位(是开区间不取本身),第三个参数1是步长,每个都取,负号表示从右往左取 三、SQL实现方法: 1如果成绩大于等于600分,则返回优秀,否则返回普通 代码如下: SELECT姓名,总成绩,IF(总成绩600,优秀,普通)AS是否优秀FROM 2如果成绩大于等于600分,则返回优秀,大于等于500分小于600分返回普通,小于500分返回不优秀 代码如下: SELECT姓名,总成绩,IF(总成绩600,优秀,IF(总成绩500,普通,不优秀))AS是否优秀FROM 上面这条查询也可以写成下面这样: SELECT姓名,总成绩, CASEWHEN总成绩600THEN优秀 WHEN总成绩500THEN普通 ELSE不优秀 ENDAS是否优秀 FROM 3如果成绩大于600分并且性别为男,则返回男优秀,如果成绩大于600分且性别为女,返回女优秀,否则返回不优秀 代码如下: SELECT姓名,总成绩, CASEWHEN总成绩600AND性别男THEN男优秀 WHEN总成绩600AND性别女THEN女优秀 ELSE普通 ENDAS是否优秀 FROM 在MYSQL中AND和OR函数,布尔类型也是只有True和False两种取值 NOT符号是!非 AND符号是且 OR符号是或 XOR表示异或 aXORb这个逻辑运算相当于aAND(NOTb)或者(NOTa)ANDb 算法与Excel一样 4如果语文成绩大于120分,或者数学成绩大于120分,则返回单科优秀,否则返回普通: SELECT姓名,语文,数学, CASEWHEN语文120OR数学120THEN单科优秀 ELSE普通 ENDAS是否优秀 FROM 5花名册里技能字段如果包含剑字则返回剑法,如果包含刀字,则返回刀法,除此之外返回其他 代码如下: SELECT姓名,技能, CASEWHEN技能REGEXP〔刀〕THEN刀法 WHEN技能REGEXP〔剑〕THEN剑法 ELSE其他 ENDAS技能类型 FROM 6从字符串里提取指定位置的文本,本例从地址列文本里面进行提取省名、市名、县名 代码如下: SELECT地址, MID(地址,1,LOCATE(省,地址))AS省, MID(地址,LOCATE(省,地址)1,locate(市,地址)LOCATE(省,地址))AS市, MID(地址,LOCATE(市,地址)1,locate(县,地址)LOCATE(市,地址))AS县 FROMtemp3; 这里MID函数不同于Excel,SQL里是可以引入负数作为第二个参数,代表的意思是从右往左,locate本身就是定位的意思,这个函数相当于Excel里的FIND函数 比如SELECTmid(basketball,4);这里省略了第三个参数,从这个字符最右往左数第4位开始取数,一直向右取到完 SELECTmid(basketball,4,2);如果加上第三个参数,从这个字符最右往左数第4位开始取数,取数长度为2位 本例还可以用LEFT和RIGHT函数进行提取:代码如下 SELECT地址, LEFT(地址,LOCATE(省,地址))AS省, MID(地址,LOCATE(省,地址)1,locate(市,地址)LOCATE(省,地址))AS市, RIGHT(地址,CHARLENGTH(地址)LOCATE(市,地址))AS县 FROMtemp3; 四、Tableau实现: 1如果成绩大于等于600分,则返回优秀,否则返回普通 打开Tableau软件,连接到工作表成绩单,然后创建一个计算字段输入公式: IF〔总成绩〕600THEN优秀ELSE不优秀END 2如果成绩大于等于600分,则返回优秀,大于等于500分小于600分返回普通,小于500分返回不优秀 计算字段代码如下: IF〔总成绩〕600THEN优秀 ELSEIF〔总成绩〕500THEN普通 ELSE不优秀END 3如果成绩大于600分并且性别为男,则返回男优秀,如果成绩大于600分且性别为女,返回女优秀,否则返回不优秀 计算字段代码如下: IF〔总成绩〕600AND〔性别〕男THEN男优秀 ELSEIF〔总成绩〕600AND〔性别〕女THEN女优秀 ELSE普通END 4如果语文成绩大于120分,或者数学成绩大于120分,则返回单科优秀,否则返回普通 代码如下: IF〔语文〕120OR〔数学〕120THEN单科优秀 ELSE普通END 5花名册里技能字段如果包含剑字则返回剑法,如果包含刀字,则返回刀法,除此之外返回其他 新建Tableau工作簿,并连接到花名册表,新建计算字段技能类型,代码如下: IFCONTAINS(〔技能〕,剑)THEN剑法 ELSEIFCONTAINS(〔技能〕,刀)THEN刀法 ELSE其他END CONTAINS函数是Tableau特有的,返回的也是一个布尔逻辑值,相当于SQL中的WHEN技能REGEXP〔刀〕(这里是正则查找,返回的也是逻辑值),也相当于Excel中的ISNUMBER(FIND(刀,狂风刀法,1)) 6从字符串里提取指定位置的文本,本例从地址列文本里面进行提取省名、市名、县名 代码: 计算字段省:MID(〔地址〕,1,FIND(〔地址〕,省)) 计算字段市:MID(〔地址〕,FIND(〔地址〕,省)1,FIND(〔地址〕,市)FIND(〔地址〕,省)) 计算字段县:MID(〔地址〕,FIND(〔地址〕,市)1,LEN(〔地址〕)FIND(〔地址〕,市)) 需要注意,Tableau中的FIND函数和Excel中的FIND函数两个参数的位置正好相反 到此四种工具全部完成任务,如果觉得有用请点下关注,可以和本人互动交流,共同学习进步