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实现dict版图遍历示例
Feb 19 Python
Python程序中使用SQLAlchemy时出现乱码的解决方案
Apr 24 Python
详解Python中用于计算指数的exp()方法
May 14 Python
轻松实现python搭建微信公众平台
Feb 16 Python
python二分查找算法的递归实现方法
May 12 Python
Python cookbook(数据结构与算法)将名称映射到序列元素中的方法
Mar 22 Python
python生成每日报表数据(Excel)并邮件发送的实例
Feb 03 Python
python实现AES加密和解密
Mar 27 Python
基于python的ini配置文件操作工具类
Apr 24 Python
详解python解压压缩包的五种方法
Jul 05 Python
自定义实现 PyQt5 下拉复选框 ComboCheckBox的完整代码
Mar 30 Python
Python基于Faker假数据构造库
Nov 30 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过滤所有恶意字符(批量过滤post,get敏感数据)
2014/03/18 PHP
php和editplus正则表达式去除空白行
2015/04/17 PHP
php发送邮件的问题详解
2015/06/22 PHP
PHP Smarty模版简单使用方法
2016/03/30 PHP
php批量转换文件夹下所有文件编码的函数类
2017/08/06 PHP
apache集成php7.3.5的详细步骤
2019/06/20 PHP
利用JQuery为搜索栏增加tag提示
2009/06/22 Javascript
jQuery EasyUI API 中文文档 DateTimeBox日期时间框
2011/10/16 Javascript
转换字符串为json对象的方法详解
2013/11/29 Javascript
Jquery getJSON方法详细分析
2013/12/26 Javascript
JavaScript极简入门教程(一):基础篇
2014/10/25 Javascript
jQuery图片特效插件Revealing实现拉伸放大
2015/04/22 Javascript
jQuery获取页面元素绝对与相对位置的方法
2015/06/10 Javascript
Javascript小技能总结(推荐)
2016/06/02 Javascript
JavaScript注册时密码强度校验代码
2017/06/30 Javascript
深入浅析ES6 Class 中的 super 关键字
2017/10/20 Javascript
vue-resource请求实现http登录拦截或者路由拦截的方法
2018/07/11 Javascript
详解如何在webpack中做预渲染降低首屏空白时间
2018/08/22 Javascript
简谈创建React Component的几种方式
2019/06/15 Javascript
Python多线程threading和multiprocessing模块实例解析
2018/01/29 Python
Python中flatten( )函数及函数用法详解
2018/11/02 Python
一篇文章搞定Python操作文件与目录
2019/08/13 Python
python 画条形图(柱状图)实例
2020/04/24 Python
pytorch中的weight-initilzation用法
2020/06/24 Python
Dockers鞋官网:Dockers Shoes
2018/11/13 全球购物
食品安全责任书
2014/04/15 职场文书
初三新学期计划书
2014/05/03 职场文书
合作意向书
2014/07/30 职场文书
学校领导班子四风问题整改意见
2014/10/02 职场文书
报名委托书
2015/01/29 职场文书
毕业典礼邀请函
2015/01/31 职场文书
2015年社区矫正工作总结
2015/04/21 职场文书
2016年感恩节活动总结大全
2016/04/01 职场文书
Win10系统下配置Java环境变量
2021/06/13 Java/Android
Linux下使用C语言代码搭建一个简单的HTTP服务器
2022/04/13 Servers
Oracle 多表查询基本语法实例
2022/04/18 Oracle