主要是记录一个采坑的过程. 当字符串 的 " " 和 pandas 中的 " " , NaN不是一个概念 .

需求

一个小伙伴要用 pandas 来处理一个, 表格填充的的问题, 脱敏数据大致是这样的.

区域名称 门店 店组
龙华新城大区 壹城中心店 壹城中心一组
益田大区 皇岗口岸店 皇岗口岸一组
双龙大区 龙城中央旗舰店 AAA店
深西大区 德佑麒麟A组
A宏畅房地产经纪有限责任公司 A地产经纪有限责任公司门店
宏畅房地产经纪有限责任公司 B地产经纪有限责任公司门店
东部 微地产瑞凯洪湖A店
景恒房地产有限公司 D景恒房地产有限公司门店
龙华新城大区 丰润花园店 丰润花园一组

现在想取一个 门店 字段, 新增或者覆盖 都可以, 取的逻辑是: "获取 门店 字段的值, 如果是值, 则选择 店组 字段的值.

咋一看, (不考虑性能, 只管实现哈), 这不简单嘛,都不想考虑用什么 apply, 遍历 DataFrame 的每一行, 然后判断就好了.

踩过过程

通常我是先测试下, 与其说是测试, 其实就是百度下api, 根本就记不住的, 要是没有搜索引擎, 写代码立刻就废掉了.

先来波测试

import pandas as pd
df = pd.DataFrame({ "a":[1,2,3,4,5,6],
"门店": ["甲店", "", "", "丙店", "", "丁店"],
"店组": ["DD", "", "AA", "", "丁店", ""]
}) print(df)
a	门店	    店组
0 1 甲店 DD
1 2
2 3 AA
3 4 丙店
4 5 丁店
5 6 丁店

为了演示方便, 这里选择新增 "新门店"字段, 不覆盖原来的哦 (如果 "门店", 没有值, 就取 "店组" 的值)

for 行号, 行值 in df.iterrows():   

    df.loc[行号, "新门店"] =  行值['门店'] or 行值["店组"]

print(df)
    a	门店	店组	新门店
0 1 甲店 DD 甲店
1 2
2 3 AA AA
3 4 丙店 丙店
4 5 丁店 丁店
5 6 丁店 丁店

测试完美通过, 然后就开始整了.

翻车1次

df = pd.read_excel("门店选择.xlsx")

# 新增 "新门店"字段 也行 如果 "门店", 没有值, 就取 "店组" 的值
for 行号, 行值 in df.iterrows(): df.loc[行号, "新门店"] = 行值['门店'] or 行值["店组"] print(df)
区域名称 门店 店组 新门店
0 龙华新城大区 壹城中心店 壹城中心一组 壹城中心店
1 益田大区 皇岗口岸店 皇岗口岸一组 皇岗口岸店
2 双龙大区 龙城中央旗舰店 AAA店 龙城中央旗舰店
3 深西大区 NaN 德佑麒麟A组 NaN
4 A宏畅房地产经纪有限责任公司 A地产经纪有限责任公司门店 NaN A地产经纪有限责任公司门店
5 深圳市宏畅房地产经纪有限责任公司 NaN B地产经纪有限责任公司门店 NaN
6 东部 微地产瑞凯洪湖A店 NaN 微地产瑞凯洪湖A店
7 深圳市景恒房地产有限公司 NaN D景恒房地产有限公司门店 NaN
8 龙华新城大区 丰润花园店 丰润花园一组 丰润花园店

新门店字段, 出大事了, 并没有匹配到空值, 但是我上面的测试是没有问题. 突然有点紧张, 这就是 所谓的 bug 呀.

又想吐槽下 关于 bug 了. 我认为什么是 bug 呢, 测试没有问题, 真正用的时候, 有问题了, 而且不太轻易发现. 但更多时候, 我发现小伙伴总是喜欢滥用这个词, 都是写代码还好, 都明白, 很多是功能没有实现, 就暂时敷衍下, 说是bug, 其实就是写完, 很多时候. 但, 更有趣的是, 跟我们对接的业务却总爱说 bug, 动不动就说是 bug, 一行代码都没参与过的人, 却整天说 bug, 就莫名想吐槽下, 也没有别的意思, 有点滑稽哈哈.

BUG 定位

初级判断, 就是, 明明是空值, 却被认为是 True 呗.

for 行号, 行值 in df.iterrows():   

    print(行号, 行值) if 行值["门店"] == "" else print("没匹到空值")
没匹到空值
没匹到空值
没匹到空值
没匹到空值
没匹到空值
没匹到空值
没匹到空值
没匹到空值
没匹到空值

卧槽, 真的是报警了, 明明有空值, 去哪了了呢???

for 行号, 行值 in df.iterrows():

    # if 行值["门店"] == '': print(行号, 行值)
#if 行值["门店"] == None: print(行号, 行值)
# if 行值["门店"] == 'nan': print(行号, 行值) if 行值["门店"] == 'NaN': print(行号, 行值)

可以看到, 字符串的 " ", 在 pandas 里面, " ", None, 'NaN', 'nan' 都是匹不上的.

临时解决

当时有有点蒙圈, 只想这, 立马先解决, 不匹了, 直接填充, 然后判断吧.

df = pd.read_excel("门店选择.xlsx")

# 将整个表的的 缺失值 都填充为 "缺失值"
df = df.fillna("缺失值") for 行号, 行值 in df.iterrows(): df.loc[行号, "新门店"] = 行值["门店"] if (行值["门店"] != "缺失值") else 行值["店组"] print(df)
区域名称 门店 店组 新门店
0 龙华新城大区 壹城中心店 壹城中心一组 壹城中心店
1 益田大区 皇岗口岸店 皇岗口岸一组 皇岗口岸店
2 双龙大区 龙城中央旗舰店 AAA店 龙城中央旗舰店
3 深西大区 缺失值 德佑麒麟A组 德佑麒麟A组
4 A宏畅房地产经纪有限责任公司 A地产经纪有限责任公司门店 缺失值 A地产经纪有限责任公司门店
5 深圳市宏畅房地产经纪有限责任公司 缺失值 B地产经纪有限责任公司门店 B地产经纪有限责任公司门店
6 东部 微地产瑞凯洪湖A店 缺失值 微地产瑞凯洪湖A店
7 深圳市景恒房地产有限公司 缺失值 D景恒房地产有限公司门店 D景恒房地产有限公司门店
8 龙华新城大区 丰润花园店 丰润花园一组 丰润花园店

可以, 算是临时解决了这个 BUG. 但这并非是一个好的方式. 原因还是在于 pandas 的 NaN 和 咱平常的 "" 缺失值不是类对象.

BUG 根源 - NaN 和 ""

查了下文档才出坑. 在 Pandas 中, 对于缺失值, 默认会以 NaN 这个 pandas 专属的标志来表示. 但它并不是一个 数字, 或字符串 或 None, 因此, 是 不能和字符串 "" 来比较的.

pandas 中, 只能用 pd.isnull(), .. 等几个相关的方法来判断 '空值' NaN

  • pd.isnull ( ) ; pd.notnull ( )

  • pd.isna ( ) ; pd.notna( )

关于缺失值处理, 有两个极为重要的方法: dropna(), fillna()

真正解决:

# 直接覆盖原有的 "门店" 也行 如果 "门店", 没有值, 就取 "店组" 的值
df = pd.read_excel("门店选择.xlsx") for 行号, 行值 in df.iterrows(): df.loc[行号, "新门店"] = 行值['门店'] if pd.notnull(行值['门店']) else 行值["店组"]

最后呢, 再测试一下, 这下用 pd.isnull () 或者 pd.isna() 就能匹配上 空值了.

df = pd.read_excel("门店选择.xlsx")

for 行号, 行值 in df.iterrows():   

    print(行号) if pd.isnull(行值["门店"]) else print("没匹到空值")
没匹到空值
没匹到空值
没匹到空值
3
没匹到空值
5
没匹到空值
7
没匹到空值

就记录下这个采坑, 记住空判断, 在 pandas 中一定要**用 pd.isna() 或者 pd.isnull() **, 尤其在遍历行的时候, 经常习惯性用 " " 或, "NaN" 或 None 等来处理.

虽然这个问题小, 但也是经验的累积嘛, 所谓, 吃一堑, 长一智嘛, 一点点积累起来, 就是经验了.

采坑 - 字符串的 "" 与 pd.isnull()的更多相关文章

  1. 采坑:python base64

    需求:  读取文本内容,对字符串进行base64加密 >>> str = 'aaaaaaaaaaaaaaaaaaa\nbbbbbbbbbbbbbbbbbbbbbbbbbbb\nccc ...

  2. 从源码看Spring Security之采坑笔记(Spring Boot篇)

    一:唠嗑 鼓捣了两天的Spring Security,踩了不少坑.如果你在学Spring Security,恰好又是使用的Spring Boot,那么给我点个赞吧!这篇博客将会让你了解Spring S ...

  3. Redis采坑(一)——数据无法插入,内存溢出

    一.采坑背景 在最大数据分析的过程中,redis是被当做热数据的缓存库使用的,在某一天中,redis数据库热数据无法插入,此时数据量大概在100万左右,很是纠结,为什么不能插入?程序的错误,不可能,没 ...

  4. @WebFilter 的使用及采坑

    @WebFilter@WebFilter 用于将一个类声明为过滤器,该注解将会在部署时被容器处理,容器将根据具体的属性配置将相应的类部署为过滤器.该注解具有下表给出的一些常用属性 ( 以下所有属性均为 ...

  5. 聊聊.netcore采坑那一些事之系统时间and文件路径

    聊聊.netcore采坑那一些事之系统时间and文件路径 Hi,小伙伴大家好,最近工作比较忙,很久没有和大家分享点东西了.这个周末都加了两天班.公司的新项目都是采用.netcore来开发,在开发过程中 ...

  6. java采坑之路

    判断相等 字符串判断相等         String str1 = null;         String str2 = "java金融";        // str1.eq ...

  7. Cloudera Manager 5.9 和 CDH 5.9 离线安装指南及个人采坑填坑记

    公司的CDH早就装好了,一直想自己装一个玩玩,最近组了台电脑,笔记本就淘汰下来了,加上之前的,一共3台,就在X宝上买了CPU和内存升级了下笔记本,就自己组了个集群. 话说,好想去捡垃圾,捡台8核16线 ...

  8. angular采坑记录

    在angular中会遇到一些莫名的问题,导致不能完成想要的功能,可能是某项用法使用错误,或许是angular相对应不支持,或者是我们功力根本就没有达到.为了在每次采坑之后能有所收获,再遇到时能理解其根 ...

  9. 分布式改造剧集之Redis缓存采坑记

    Redis缓存采坑记 ​ 前言 ​ 这个其实应该属于分布式改造剧集中的一集(第一集见前面博客:http://www.cnblogs.com/Kidezyq/p/8748961.html),本来按照顺序 ...

  10. Hadoop环境搭建--Docker完全分布式部署Hadoop环境(菜鸟采坑吐血整理)

    系统:Centos 7,内核版本3.10 本文介绍如何从0利用Docker搭建Hadoop环境,制作的镜像文件已经分享,也可以直接使用制作好的镜像文件. 一.宿主机准备工作 0.宿主机(Centos7 ...

随机推荐

  1. element-ui中el-table多层数组渲染问题

    tableData: [ { name: '国家出资人', list: [ { name: '2011', value: '0' }, { name: '2012', value: '0' }, { ...

  2. 【软件开发】Git 概念与常用命令

    [软件开发]Git 概念与常用命令 Git 概念 存储方式 Git 是分布式存储,每一个 clone 下来的仓库都可以看成独立的个体,只是 Git 有提供同步功能,因此 Git 支持离线使用,因为本质 ...

  3. JavaUtils - [04] 代码生成器(新)

    题记部分 001 || 引入依赖 <!-- Code Generator --> <dependency> <groupId>com.baomidou</gr ...

  4. 执行shell脚本报错:Syntax error: word unexpected (expecting "in")

    检查语法无误后,考虑是脚本文件换行符的问题. vs创建的文件默认以CRLF(0D0A)换行. 然而对于换行,windows用CRLF(0D0A)表示,linux用LF(0A)表示. 切换脚本文件换行符 ...

  5. 记一次Microsoft.Toolkit.Mvvm(MVVM Toolkit)的兼容性问题

    今天在目标框架为framework4.6.1的wpf项目中使用Microsoft.Toolkit.Mvvm7.1.1出现了一个比较怪异的编译时错误,前提是打开了 工具>选项>环境>预 ...

  6. wikidata介绍和查询

      Wikidata是一个大型结构化开源知识图,为维基百科等项目提供支持.我们可使用SPARQL(Wikidata官方Tutorial)对其进行查询.SPARQL是一种专为 RDF(Resource ...

  7. Echarts与Vue3中获取DOM节点可能出现的异常错误

    useTemplateRef 的简单介绍 官方:返回一个浅层 ref,其值将与模板中的具有匹配 ref attribute 的元素或组件同步. 参数匹配机制‌:useTemplateRe的参数需与模板 ...

  8. layui 自动触发radio和select

    layui对radio和select做了包装,正常用jquery选中后使用trigger不起作用. 那么,怎么让其自动触发呢? 对radio来说,必须在$选中后.next('.layui-form-r ...

  9. 对接服务升级后仅支持tls1.2,jdk1.7默认使用tls1.0,导致调用失败

    背景 如标题所说,我手里维护了一个重要的老项目,使用jdk1.7,里面对接了很多个第三方服务,协议多种多样,其中涉及http/https的,调用方式也是五花八门,比如:commons-httpclie ...

  10. pip 提示import error,cannot import name locations

    出现这个问题的原因: 环境中没有安装年文件 安装了,环境路径错误 解决如下: 首先 执行升级命令 升级到最新 python -m pip install -U pip 再到site-packages目 ...