采坑 - 字符串的 "" 与 pd.isnull()
主要是记录一个采坑的过程. 当字符串 的 " " 和 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()的更多相关文章
- 采坑:python base64
需求: 读取文本内容,对字符串进行base64加密 >>> str = 'aaaaaaaaaaaaaaaaaaa\nbbbbbbbbbbbbbbbbbbbbbbbbbbb\nccc ...
- 从源码看Spring Security之采坑笔记(Spring Boot篇)
一:唠嗑 鼓捣了两天的Spring Security,踩了不少坑.如果你在学Spring Security,恰好又是使用的Spring Boot,那么给我点个赞吧!这篇博客将会让你了解Spring S ...
- Redis采坑(一)——数据无法插入,内存溢出
一.采坑背景 在最大数据分析的过程中,redis是被当做热数据的缓存库使用的,在某一天中,redis数据库热数据无法插入,此时数据量大概在100万左右,很是纠结,为什么不能插入?程序的错误,不可能,没 ...
- @WebFilter 的使用及采坑
@WebFilter@WebFilter 用于将一个类声明为过滤器,该注解将会在部署时被容器处理,容器将根据具体的属性配置将相应的类部署为过滤器.该注解具有下表给出的一些常用属性 ( 以下所有属性均为 ...
- 聊聊.netcore采坑那一些事之系统时间and文件路径
聊聊.netcore采坑那一些事之系统时间and文件路径 Hi,小伙伴大家好,最近工作比较忙,很久没有和大家分享点东西了.这个周末都加了两天班.公司的新项目都是采用.netcore来开发,在开发过程中 ...
- java采坑之路
判断相等 字符串判断相等 String str1 = null; String str2 = "java金融"; // str1.eq ...
- Cloudera Manager 5.9 和 CDH 5.9 离线安装指南及个人采坑填坑记
公司的CDH早就装好了,一直想自己装一个玩玩,最近组了台电脑,笔记本就淘汰下来了,加上之前的,一共3台,就在X宝上买了CPU和内存升级了下笔记本,就自己组了个集群. 话说,好想去捡垃圾,捡台8核16线 ...
- angular采坑记录
在angular中会遇到一些莫名的问题,导致不能完成想要的功能,可能是某项用法使用错误,或许是angular相对应不支持,或者是我们功力根本就没有达到.为了在每次采坑之后能有所收获,再遇到时能理解其根 ...
- 分布式改造剧集之Redis缓存采坑记
Redis缓存采坑记 前言 这个其实应该属于分布式改造剧集中的一集(第一集见前面博客:http://www.cnblogs.com/Kidezyq/p/8748961.html),本来按照顺序 ...
- Hadoop环境搭建--Docker完全分布式部署Hadoop环境(菜鸟采坑吐血整理)
系统:Centos 7,内核版本3.10 本文介绍如何从0利用Docker搭建Hadoop环境,制作的镜像文件已经分享,也可以直接使用制作好的镜像文件. 一.宿主机准备工作 0.宿主机(Centos7 ...
随机推荐
- Java 加密和解密
在 Java 中,加密和解密通常通过 Java Cryptography Architecture (JCA) 和 Java Cryptography Extension (JCE) 实现.以下是常见 ...
- 26考研高数习题:1.1. 分段&复合函数
§1.1. 分段&复合函数 更详细的考研数学精讲请访问「荒原之梦考研数学」 Ultra 版:www.zhaokaifeng.com 001 题目 设 \(g\left(x\right) = ...
- VSCode ESLint规则警告屏蔽方法
举例:要屏蔽"Missing trailing comma"或"comma-dangle"警告,你可以使用ESLint的配置选项来设置规则.下面是一些方法,你可 ...
- mysql 查询结果为空时值时执行后面的sql语句
sql server支持变量所以一般使用方法如下: DECLARE @Val varchar(50) select @Val = param_value where t_param where par ...
- Python脚本 | 提取pdf页面为jpg
功能: 提取pdf文件中的每一页,输出为jpg文件 以markdown语法写入文本文件 将该文本复制到剪贴板 # python 3.10 # ! 运行在 conda-myv虚拟环境 import fi ...
- rust学习笔记(8)
cargo cargo是一个用来帮助控制项目开发的工具 cargo.toml 这是一个用来管理项目的文件 首先是[package]部分 [package] name = "foo" ...
- mysql - 视图的操作 创建,修改,删除,查看
只保存sql逻辑,不保存查询结果 视图可以看作是封装了多条sql语句,之后使用的时候就像普通表一样,而这个表上的字段则是创建视图时,select 后边跟的字段,支持列的别名. 创建 语法: creat ...
- Bash Shell 30min 过家家
带你捅破窗户纸 - 备注 : @博客园 : 1. 为什么不支持 pdf 上传了呀 2. 网站分类不好用 3. 排版OA工具升级下, 例如 markdown 写出来好丑. 尝试升级下呢 ? 后记: 学如 ...
- MongoDB入门介绍与案例分析
一.MongoDB 数据库定位 首先我们来看一下 MongoDB 是什么样的数据库.数据库分两大类: OLTP(Online Transaction Processing)联机事务处理. OLAP(O ...
- sourcetree 重新设置git账号密码
设置提交git账号邮箱 到项目根目录,执行 vi ~/.gitconfig ,直接编辑修改即可 重新设置git登陆账号密码 打开 sourcetree 的偏好设置,选择高级,然后移除即可