Python连接HDFS实现文件上传下载及Pandas转换文本文件到CSV操作


Posted in Python onJune 06, 2020

1. 目标

通过hadoop hive或spark等数据计算框架完成数据清洗后的数据在HDFS上

爬虫和机器学习在Python中容易实现

在Linux环境下编写Python没有pyCharm便利

需要建立Python与HDFS的读写通道

2. 实现

安装Python模块pyhdfs

版本:Python3.6, hadoop 2.9

读文件代码如下

from pyhdfs import HdfsClient
client=HdfsClient(hosts='ghym:50070')#hdfs地址
res=client.open('/sy.txt')#hdfs文件路径,根目录/
for r in res:
 line=str(r,encoding='utf8')#open后是二进制,str()转换为字符串并转码
 print(line)

写文件代码如下

from pyhdfs import HdfsClient
client=HdfsClient(hosts='ghym:50070',user_name='hadoop')#只有hadoop用户拥有写权限
str='hello world'
client.create('/py.txt',str)#创建新文件并写入字符串

上传本地文件到HDFS

from pyhdfs import HdfsClient
client = HdfsClient(hosts='ghym:50070', user_name='hadoop')
client.copy_from_local('d:/pydemo.txt', '/pydemo')#本地文件绝对路径,HDFS目录必须不存在

3. 读取文本文件写入csv

Python安装pandas模块

确认文本文件的分隔符

# pyhdfs读取文本文件,分隔符为逗号,
from pyhdfs import HdfsClient
client = HdfsClient(hosts='ghym:50070', user_name='hadoop')
inputfile=client.open('/int.txt')
# pandas调用读取方法read_table
import pandas as pd
df=pd.read_table(inputfile,encoding='gbk',sep=',')#参数为源文件,编码,分隔符
# 数据集to_csv方法转换为csv
df.to_csv('demo.csv',encoding='gbk',index=None)#参数为目标文件,编码,是否要索引

补充知识:记 读取hdfs 转 pandas 再经由pandas转为csv的一个坑

工作流程是这样的:

读取 hdfs 的 csv 文件,采用的是 hdfs 客户端提供的 read 方法,该方法返回一个生成器。

将读取到的数据按 逗号 处理,变为一个二维数组。

将二维数组传给 pandas,生成 df。

经若干处理后,将 df 转为 csv 文件并写入hdfs。

问题是这样的:

正常的数据:

ZERO,MEAN,STD,CV,INC,OPP,CS,IS_OUTNET

0,9.233,2.445,0.265,1.202,241,1,0

0,8.667,1.882,0.217,1.049,179,1,0

三行数据,正常走流程,没有任何问题。

异常数据:

ZERO,MEAN,STD,CV,INC,OPP,CS,IS_OUTNET,probability,prediction

0,9.233,2.445,0.265,1.202,241,1,0,'[0.9653901649086855,0.03460983509131456]',0.0

0,8.667,1.882,0.217,1.049,179,1,0,'[0.9653901649086855,0.03460983509131456]',0.0

在每一行中都会有一个数组类似的数据,有一对引号包起来,中间存在逗号,不可以拆分。

为此,我的做法如下:

匹配逗号是被成对引号包围的字符串。

将匹配到的字符串中的逗号替换为特定字符。

将替换后的新字符串替换回原字符串。

在将原字符串中的特定字符串替换为逗号。

本来这样做没有什么问题,但是在经由pandas转为csv的时候,发现原来带引号的字符串变为了前后各带三个引号。

源数据:

Python连接HDFS实现文件上传下载及Pandas转换文本文件到CSV操作

处理后的数据:

Python连接HDFS实现文件上传下载及Pandas转换文本文件到CSV操作

方法如下:

Python连接HDFS实现文件上传下载及Pandas转换文本文件到CSV操作

仔细研究对比了下数据,发现数据里的引号其实只是在纯文本文件中用来标识其为字符串,并不应该存在于实际数据中。

Python连接HDFS实现文件上传下载及Pandas转换文本文件到CSV操作

而我每次匹配后都是原封不动替换回去,譬如:

源数据:

"[0.9653901649086855,0.03460983509131456]"

匹配替换后:

"[0.9653901649086855${dot}0.03460983509131456]"

这样传给pandas,它就会认为这个数据是带引号的,在重新转为csv的时候,就会进行转义等操作,导致多出很多引号。

所以解决办法就是在替换之前,将匹配时遇到的引号也去掉:

PATTERN = '(?<=(?P<quote>[\'\"]))([^,]+,[^,]+)+?(?=(?P=quote))'

中间 ([^,]+,[^,]+)+? 要用+?,因为必须确定是有这样的组合才可以,并且非贪婪模式,故不可 ? 或者 *?

Python连接HDFS实现文件上传下载及Pandas转换文本文件到CSV操作

(ps:为了方便后面引用前面的匹配,我在环视匹配中创建了一个组)

再来个整体效果:

Python连接HDFS实现文件上传下载及Pandas转换文本文件到CSV操作

为了说明效果,引用pandas的自带读取csv方法:

Python连接HDFS实现文件上传下载及Pandas转换文本文件到CSV操作

可以看到pandas读取出的该位置数据也是字符串,引号正是作为一个字符串声明而存在。

再次修改正则:

def split_by_dot_escape_quote(string):
  """
  按逗号分隔字符串,若其中有引号,将引号内容视为整体
  """
  # 匹配引号中的内容,非贪婪,采用正向肯定环视,
  # 当左引号(无论单双引)被匹配到,放入组quote,
  # 中间的内容任意,但是要用+?,非贪婪,且至少有一次匹配到字符,
  # 若*?,则匹配0次也可,并不会匹配任意字符(环视只匹配位置不匹配字符),
  # 由于在任意字符后面又限定了前面匹配到的quote,故只会匹配到",
  # +?则会限定前面必有字符被匹配,故"",或引号中任意值都可匹配到
  pattern = re.compile('(?=(?P<quote>[\'\"])).+?(?P=quote)')
  rs = re.finditer(pattern, string)
  for data in rs:
    # 匹配到的字符串
    old_str = data.group()
    # 将匹配到的字符串中的逗号替换为特定字符,
    # 以便还原到原字符串进行替换
    new_str = old_str.replace(',', '${dot}')
    # 由于匹配到的引号仅为字符串申明,并不具有实际意义,
    # 需要把匹配时遇到的引号都去掉,只替换掉当前匹配组的引号
    new_str = re.sub(data.group('quote'), '', new_str)
    string = string.replace(old_str, new_str)
  sps = string.split(',')
  return map(lambda x: x.replace('${dot}', ','), sps)
 
 
s = '"2011,603","3510006998","F","5","5","0",""'
print(list(split_by_dot_escape_quote(s)))

运行结果如下:

Python连接HDFS实现文件上传下载及Pandas转换文本文件到CSV操作

之前想的正则有些复杂,反而偏离了本意,还是对正则的认识不够深。

以上这篇Python连接HDFS实现文件上传下载及Pandas转换文本文件到CSV操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
TF-IDF与余弦相似性的应用(二) 找出相似文章
Dec 21 Python
Python使用smtp和pop简单收发邮件完整实例
Jan 09 Python
python 输出上个月的月末日期实例
Apr 11 Python
Python中pillow知识点学习
Apr 30 Python
对python3新增的byte类型详解
Dec 04 Python
django中上传图片分页三级联动效果的实现代码
Aug 30 Python
pip install python 快速安装模块的教程图解
Oct 08 Python
Python Tkinter Entry和Text的添加与使用详解
Mar 04 Python
Python CategoricalDtype自定义排序实现原理解析
Sep 11 Python
Python 实现PS滤镜的旋涡特效
Dec 03 Python
python实现xml转json文件的示例代码
Dec 30 Python
python神经网络 tf.name_scope 和 tf.variable_scope 的区别
May 04 Python
完美解决python针对hdfs上传和下载的问题
Jun 05 #Python
python读取hdfs并返回dataframe教程
Jun 05 #Python
python pymysql链接数据库查询结果转为Dataframe实例
Jun 05 #Python
python mysql中in参数化说明
Jun 05 #Python
JAVA SWT事件四种写法实例解析
Jun 05 #Python
pandas 像SQL一样使用WHERE IN查询条件说明
Jun 05 #Python
基于Python爬虫采集天气网实时信息
Jun 05 #Python
You might like
社区(php&amp;&amp;mysql)一
2006/10/09 PHP
Linux下将excel数据导入到mssql数据库中的方法
2010/02/08 PHP
两个开源的Php输出Excel文件类
2010/02/08 PHP
Zend的MVC机制使用分析(一)
2013/05/02 PHP
php的instanceof和判断闭包Closure操作示例
2020/01/26 PHP
jQuery 1.5 源码解读 面向中高阶JSER
2011/04/05 Javascript
javascript学习基础笔记之DOM对象操作
2011/11/03 Javascript
当达到输入长度时表单自动切换焦点
2014/04/06 Javascript
JavaScript实现文字与图片拖拽效果的方法
2015/02/16 Javascript
javascript this详细介绍
2016/09/19 Javascript
jquery判断页面网址是否有效的两种方法
2016/12/11 Javascript
Bootstrap源码解读网格系统(3)
2016/12/22 Javascript
用director.js实现前端路由使用实例
2017/01/27 Javascript
vue自定义指令实现方法详解
2019/02/11 Javascript
JS数组降维的实现Array.prototype.concat.apply([], arr)
2020/04/28 Javascript
[14:00]DOTA2国际邀请赛史上最长大战 赛后专访B神
2013/08/10 DOTA
Python实现图像几何变换
2015/07/06 Python
一波神奇的Python语句、函数与方法的使用技巧总结
2015/12/08 Python
python构建深度神经网络(DNN)
2018/03/10 Python
关于CSS Tooltips(鼠标经过时显示)的效果
2013/04/10 HTML / CSS
利用纯css3实现的文字亮光特效的代码演示
2014/11/27 HTML / CSS
公司庆典活动邀请函
2014/01/09 职场文书
中秋节礼品促销方案
2014/02/02 职场文书
教学个人的自我评价分享
2014/02/16 职场文书
考核评语大全
2014/04/29 职场文书
银行进社区活动总结
2014/07/07 职场文书
小学生关于梦想的演讲稿
2014/08/22 职场文书
男方婚前保证书
2015/02/28 职场文书
财务管理制度范本
2015/08/04 职场文书
物业公司管理制度
2015/08/05 职场文书
html5调用摄像头实例代码
2021/06/28 HTML / CSS
教你快速构建一个基于nginx的web集群项目
2021/11/27 Servers
Redis高可用集群redis-cluster详解
2022/03/20 Redis
漫画「古见同学有交流障碍症」第25卷封面公开
2022/03/21 日漫
Golang日志包的使用
2022/04/20 Golang
CSS 实现角标效果的完整代码
2022/06/28 HTML / CSS