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 相关文章推荐
python正则匹配查询港澳通行证办理进度示例分享
Dec 27 Python
Python卸载模块的方法汇总
Jun 07 Python
Python selenium 三种等待方式解读
Sep 15 Python
matplotlib中legend位置调整解析
Dec 19 Python
python ChainMap 合并字典的实现步骤
Jun 11 Python
python 判断字符串中是否含有汉字或非汉字的实例
Jul 15 Python
解决Python正则表达式匹配反斜杠''\''问题
Jul 17 Python
python 并发下载器实现方法示例
Nov 22 Python
解决pycharm每次打开项目都需要配置解释器和安装库问题
Feb 26 Python
python GUI库图形界面开发之PyQt5计数器控件QSpinBox详细使用方法与实例
Feb 28 Python
python读取文件指定行内容实例讲解
Mar 02 Python
Python常用配置文件ini、json、yaml读写总结
Jul 09 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
解决中英文字符串长度问题函数
2007/01/16 PHP
PHP实现的封装验证码类详解
2013/06/18 PHP
php中time()和mktime()方法的区别
2013/09/28 PHP
购物车实现的几种方式优缺点对比
2018/05/02 PHP
TP5框架实现上传多张图片的方法分析
2020/03/29 PHP
document.addEventListener使用介绍
2014/03/07 Javascript
JavaScript window.location对象
2014/11/14 Javascript
JS使用单链表统计英语单词出现次数
2016/06/16 Javascript
Bootstrapvalidator校验、校验清除重置的实现代码(推荐)
2016/09/28 Javascript
在一般处理程序(ashx)中弹出js提示语
2017/08/16 Javascript
深入理解ES6的迭代器与生成器
2017/08/19 Javascript
浅谈layui 绑定form submit提交表单的注意事项
2019/10/25 Javascript
vue+elementUI实现简单日历功能
2020/09/24 Javascript
CentOS 8.2服务器上安装最新版Node.js的方法
2020/12/16 Javascript
[56:21]LGD vs IG 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
python正则分组的应用
2013/11/10 Python
跟老齐学Python之print详解
2014/09/28 Python
python实现下载文件的三种方法
2017/02/09 Python
python 上下文管理器使用方法小结
2017/10/10 Python
python 识别图片中的文字信息方法
2018/05/10 Python
python 获取当天每个准点时间戳的实例
2018/05/22 Python
Python流程控制 if else实现解析
2019/09/02 Python
python的range和linspace使用详解
2019/11/27 Python
Django框架获取form表单数据方式总结
2020/04/22 Python
Python基于正则表达式实现计算器功能
2020/07/13 Python
伦敦所有西区剧院演出官方票务代理:Theatre Tickets Direct
2017/05/26 全球购物
美国背景检查、公共记录和人物搜索网站:BeenVerified
2018/02/25 全球购物
Desigual德国官网:在线购买原创服装
2018/03/27 全球购物
YBF Beauty官网:美丽挚友,美国知名彩妆品牌
2020/11/22 全球购物
印度电子产品购物网站:Vijay Sales
2021/02/16 全球购物
电钳专业个人求职信
2014/01/04 职场文书
面试后的英文感谢信
2014/02/01 职场文书
社区综治工作汇报
2014/10/27 职场文书
青年文明号创建口号大全
2015/12/25 职场文书
Mysql多层子查询示例代码(收藏夹案例)
2022/03/31 MySQL
Python中np.random.randint()参数详解及用法实例
2022/09/23 Python