Python pandas读取CSV文件的注意事项(适合新手)
作者:郝伟博士 发布时间:2021-10-12 12:07:32
目录
前言
示例文件
文件编码
空值
日期错误
函数映射
方法1:直接使用labmda表达式
方法二:使用自定义函数
方法三:使用数值字典映射
总结
前言
本文是给使用pandas的新手而写,主要列出一些常见的问题,根据笔者所踩过的坑,进行归纳总结,希望对读者有所帮助。
示例文件
将以下内容保存为文件 people.csv。
id,姓名,性别,出生日期,出生地,职业,爱好
1,张小三,m,1992-10-03,北京,工程师,足球
2,李云义,m,1995-02-12,上海,程序员,读书 下棋
3,周娟,女,1998-03-25,合肥,护士,音乐,跑步
4,赵盈盈,Female,2001-6-32,,学生,画画
5,郑强强,男,1991-03-05,南京(nanjing),律师,历史-政治
如果一切正常的话,在Jupyter Notebook 中应该显示以下内容:
文件编码
文件编码格式是最容易出错的问题之一。如果编码格式不正确,就会完全读取不出文件内容,出现类似于以下的错误, 让人完全不知所措:
---------------------------------------------------------------------------
UnicodeDecodeError Traceback (most recent call last)
<ipython-input-6-8659adefcfa6> in <module>
----> 1 pd.read_csv('people.csv', encoding='gb2312')C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\parsers.py in parser_f(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, squeeze, prefix, mangle_dupe_cols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, dialect, error_bad_lines, warn_bad_lines, delim_whitespace, low_memory, memory_map, float_precision)
683 )
684
--> 685 return _read(filepath_or_buffer, kwds)
686
687 parser_f.__name__ = nameC:\ProgramData\Anaconda3\lib\site-packages\pandas\io\parsers.py in _read(filepath_or_buffer, kwds)
455
456 # Create the parser.
--> 457 parser = TextFileReader(fp_or_buf, **kwds)
458
459 if chunksize or iterator:C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\parsers.py in __init__(self, f, engine, **kwds)
893 self.options["has_index_names"] = kwds["has_index_names"]
894
--> 895 self._make_engine(self.engine)
896
897 def close(self):C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\parsers.py in _make_engine(self, engine)
1133 def _make_engine(self, engine="c"):
1134 if engine == "c":
-> 1135 self._engine = CParserWrapper(self.f, **self.options)
1136 else:
1137 if engine == "python":C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\parsers.py in __init__(self, src, **kwds)
1915 kwds["usecols"] = self.usecols
1916
-> 1917 self._reader = parsers.TextReader(src, **kwds)
1918 self.unnamed_cols = self._reader.unnamed_cols
1919pandas\_libs\parsers.pyx in pandas._libs.parsers.TextReader.__cinit__()
pandas\_libs\parsers.pyx in pandas._libs.parsers.TextReader._get_header()
UnicodeDecodeError: 'gb2312' codec can't decode byte 0x93 in position 2: illegal multibyte sequence
目前对于中文而言,最常使用的有 utf-8 和 gb2312 两种格式,只需要指定正确的编码。在不知道编码的情况下,只需要尝试两次即可。padas默认的文件编码格式是 utf-8,所以如果出现以上错误,只需使用 encoding=gb2312 再尝试一下即可,如 pd.read_csv(file, encoding='gb2312')。
空值
空值是csv中也非常常见,比如以下内容:
import pandas as pd
df = pd.read_csv('people.csv')
v1=df['出生地'][3]
print(v1, type(v1))
输出为:
nan <class 'float'>
由此可见,空值也是有数据类型的,为 float 类型。
如何判断空值有两种方法,可以使用 math.isnan(x) 也可以使用 isinstance(float)。我们知道,DateFrame对象是包括Series对象,而在一个Series对象中,所有的数据类型默认是一样的,所以如果其数据类型推断为字符串(str),那么直接使用 math.isnan(x) 则会报错 TypeError: must be real number, not str 错误,即必需为实数,不能是字符串。所以,这时我们还需要使用 isinstance(x, flaot) 方法。
具体请看这个示例:
df.出生地=df.出生地.map(lambda x: '其他' if isinstance(x, float) else x)
df
日期错误
出生日期中,有的数据错误,如赵盈盈的出生日期是6月32号,所以报错了。对于这样类似的错误,我们可以使用函数判断的方式进行处理,具体如下。
首先,编写 isDate 函数用于判断日期是否合法。
def isDate(adate):
try:
sects = adate.split('-')
year = int(sects[0])
month = int(sects[1])
day = int(sects[2])
days = [0, 31, 29 if year % 4 == 0 else 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
return year > 0 and year < 9999 and month > 0 and month <= 12 and day > 0 and day <= days[month]
except:
return False
然后使用以下代码进行判断:
for id in df.index:
if not isDate(df.loc[id, '出生日期']):
print(df.loc[id, '出生日期'])
df.loc[id, '出生日期'] = '2000-01-01'
输出结果如下,可见错误的日期被修改成了2020年1月1日。
2001-6-32
id 姓名 性别 出生日期 出生地 职业 爱好
0 1 张小三 m 1992-10-03 北京 工程师 足球
1 2 李云义 m 1995-02-12 上海 程序员 读书 下棋
2 3 周娟 女 1998-03-25 合肥 护士 音乐,跑步
3 4 赵盈盈 Female 2000-01-01 NaN 学生 画画
4 5 郑强强 男 1991-03-05 南京(nanjing) 律师 历史-政治
函数映射
方法1:直接使用labmda表达式
需要对数据列进行复杂操作的时候,我们可以使用以下函数时行相应的操作。
df=df.fillna('未知')
df.爱好=df.爱好.map(lambda x: x.split(' ')[0].split('-')[0].split(',')[0])
df
方法二:使用自定义函数
在进行映射时,如果操作比较简单,可以使用字典的方式进行数值映射映射(参见下文)。但是如果操作比较复杂,则需要使用函数进行映射。请看这个示例,读取到性别时,内容有 ‘m', ‘M', ‘Female' 等内容,现在需要其全部转换为 男 或 女:
def set_sex(s):
if s.lower() == 'm' or s.lower() == 'male':
return '男'
elif s.lower() == 'female':
return '女'
return s
df = pd.read_csv('people.csv', converters={'性别': lambda x : set_sex(x)})
df
方法三:使用数值字典映射
在数据处理时,数值型往往比字符串效率更高,所以在可能的情况下,我们希望将数据转换成字符串处理。请看这个示例,将输入的数据的性别中的男性转换为1 女性转换为0。操作如下:
来源:https://blog.csdn.net/weixin_43145361/article/details/117909213


猜你喜欢
- 执行表扫描操作之前,将调用info()函数,以便为优化程序提供额外信息。优化程序所需的信息不是通过返回值给定的,你需填充存储引擎类的特定属性
- 在thoughtbot,我们用Ruby和Rails工作,但通常我们总是尝试使用最合适的语言或者框架来解决问题。我最近一直在探索机器学习技术,
- 本文实例讲述了Python基于matplotlib实现绘制三维图形功能。分享给大家供大家参考,具体如下:代码一:# coding=utf-8
- 前文已述,因为需要测试mysql的主从配置方案,所以要安装多个mysql。这次是在ubuntu kylin 14.10上安装多个mysql
- python聊天室很多人都觉得微信,QQ,ICQ(我不知道现在还能不能用了)都过于垃圾,想要自己做一个聊天室(或是聊天软件),所以我们可以自
- 过往经验总结注:笔者写本文的目的不是完整细致地描述连接的全过程,而是记录当中遇到的现象、问题,及为什么会产生这个问题的分析。所以部分过程会省
- 最近的项目需要根据用户所属时区制定一些特定策略,学习、应用了若干python3的时区转换相关知识,这里整理一部分记录下来。下面涉及的几个概念
- 数学模块import mathceil -- 上取整对一个数向上取整(进一法),取相邻最近的两个整数的最大值。import mathres
- 印象中最早看老外个人网站就挺纳闷,怎么人家都没有www,这样也可以?经过不断尝试,我发现确实不录入www要快捷的多,但不清楚怎么能做到。几年
- 异常的参数一个异常可以带上参数,可作为输出的异常信息参数。你可以通过except语句来捕获异常的参数,如下所示:变量接收的异常值通常包含在异
- 在学习MySQL的过程中,常常会测试各种参数的作用。这时候,就需要快速构建出MySQL实例,甚至主从。 考虑如下场景:譬如我想测试
- SpringBoot环境启动项目创建数据库表使用环境windows+eclipse+mysql+navicat步骤1.创建SpringBoo
- MySQL编译参数多而复杂,让新手感到很头大,如果是正式生成环境安装MySQL,没有充足的时间去研究每一个参数代表的意义,个人建议使用余洪春
- 我就废话不多说了,直接上代码吧!#方法一def list_cut(mylist,count): length=len(mylis
- SELECT语句,去除某个字段的重复信息,例如: 表名:table id uid username message dateline 1 6
- 限制访问可以基于某种权限,某些检查或者为login视图提供不同的位置,这些实现方式大致相同。一般的方法是直接在视图的 request.use
- 你同样可以使用cache标签来缓存模板片段。 在模板的顶端附近加入{% load cache %}以通知模板存取缓存标签。模板标签{% ca
- 经过dom层层注释缩小反馈终于找到问题所在。问题经过我在弹起弹窗的时候,设置了popupVisible为true然后触发了vue的updat
- 最近学习了一点python,那就试着做一做简单的编程练习。 首先是这个编程的指导图,如下:对的,类似一个简单区块链的模拟。 代码如下:cla
- 两种情况:1.带索引 2.不带索引前提介绍:方式:采用命令行的方式来模拟1.mysq由于默认是开启自动提交事务,所以首先得查看自己当前的数据