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中实现常量(Const)功能
Jan 28 Python
Python中基本的日期时间处理的学习教程
Oct 16 Python
python学习笔记之调用eval函数出现invalid syntax错误问题
Oct 18 Python
python类的继承实例详解
Mar 30 Python
Python面向对象程序设计中类的定义、实例化、封装及私有变量/方法详解
Feb 28 Python
python爬虫 模拟登录人人网过程解析
Jul 31 Python
Python imread、newaxis用法详解
Nov 04 Python
pytorch 图像预处理之减去均值,除以方差的实例
Jan 02 Python
在pytorch 中计算精度、回归率、F1 score等指标的实例
Jan 18 Python
python GUI库图形界面开发之PyQt5打开保存对话框QFileDialog详细使用方法与实例
Feb 27 Python
使用Python爬取小姐姐图片(beautifulsoup法)
Feb 11 Python
浅析Python中的套接字编程
Jun 22 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中Array2xml类实现数组转化成XML实例
2014/12/08 PHP
php使用Cookie控制访问授权的方法
2015/01/21 PHP
修改WordPress中文章编辑器的样式的方法详解
2015/12/15 PHP
jQuery对象[0]是什么含义?
2010/07/31 Javascript
JavaScript在多浏览器下for循环的使用方法
2012/11/07 Javascript
dwz 如何去掉ajaxloading具体代码
2013/05/22 Javascript
提高jQuery性能的十个诀窍
2013/11/14 Javascript
node.js中的http.response.end方法使用说明
2014/12/14 Javascript
Avalon中文长字符截取、关键字符隐藏、自定义过滤器
2016/05/18 Javascript
微信小程序开发之实现选项卡(窗口顶部TabBar)页面切换
2016/11/25 Javascript
jQury Ajax使用Token验证身份实例代码
2017/09/22 Javascript
vue.js中父组件调用子组件的内部方法示例
2017/10/22 Javascript
Vue的实例、生命周期与Vue脚手架(vue-cli)实例详解
2017/12/27 Javascript
微信小程序BindTap快速连续点击目标页面跳转多次问题处理
2019/04/08 Javascript
简单了解JavaScript异步
2019/05/23 Javascript
Vue-Cli项目优化操作的实现
2019/10/27 Javascript
vue 中的动态传参和query传参操作
2020/11/09 Javascript
一篇文章让你搞懂JavaScript 原型和原型链
2020/11/23 Javascript
Python 实现「食行生鲜」签到领积分功能
2018/09/26 Python
Mac下Anaconda的安装和使用教程
2018/11/29 Python
python ipset管理 增删白名单的方法
2019/01/14 Python
Python3 Tkinter选择路径功能的实现方法
2019/06/14 Python
Python编程实现tail-n查看日志文件的方法
2019/07/08 Python
Python关于反射的实例代码分享
2020/02/20 Python
用python介绍4种常用的单链表翻转的方法小结
2020/02/24 Python
Linux不知道文件后缀名怎么判断文件类型
2014/08/21 面试题
Why we need EJB
2016/10/20 面试题
大学生职业规划前言模板
2013/12/27 职场文书
财政局个人总结
2015/03/04 职场文书
幼儿园万圣节活动总结
2015/05/05 职场文书
学生乘坐校车安全责任书
2015/05/11 职场文书
班主任开场白
2015/06/01 职场文书
施工现场安全管理制度
2015/08/05 职场文书
遗嘱范文
2015/08/07 职场文书
go类型转换及与C的类型转换方式
2021/05/05 Golang
分享Python获取本机IP地址的几种方法
2022/03/17 Python