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转换摩斯密码示例
Feb 16 Python
Python 执行字符串表达式函数(eval exec execfile)
Aug 11 Python
Django框架中的对象列表视图使用示例
Jul 21 Python
Python内建数据结构详解
Feb 03 Python
Python合并字典键值并去除重复元素的实例
Dec 18 Python
详解python中executemany和序列的使用方法
Aug 12 Python
Python实现识别图片内容的方法分析
Jul 11 Python
Python 中的 global 标识对变量作用域的影响
Aug 12 Python
pytorch GAN生成对抗网络实例
Jan 10 Python
python对文件的操作方法汇总
Feb 28 Python
Anaconda+spyder+pycharm的pytorch配置详解(GPU)
Oct 18 Python
FP-growth算法发现频繁项集——发现频繁项集
Jun 24 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实现多张图片上传加水印技巧
2013/04/18 PHP
IE6/7/8中Option元素未设value时Select将获取空字符串
2011/04/07 Javascript
js中关于String对象的replace使用详解
2011/05/24 Javascript
如何让页面加载完成后执行js
2013/06/26 Javascript
JS实现很酷的水波文字特效实例
2015/02/26 Javascript
AngularJS表格详解及示例代码
2016/08/17 Javascript
JavaScript实现横线提示输入验证码随输入验证码输入消失的方法
2016/09/24 Javascript
微信小程序中的onLoad详解及简单实例
2017/04/05 Javascript
Vue.use源码分析
2017/04/22 Javascript
Vue Spa切换页面时更改标题的实例代码
2017/07/15 Javascript
JavaScript实现的滚动公告特效【基于jQuery】
2019/07/10 jQuery
JS访问对象两种方式区别解析
2020/08/29 Javascript
[01:08:00]Fnatic vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
把大数据数字口语化(python与js)两种实现
2013/02/21 Python
python字典多条件排序方法实例
2014/06/30 Python
python 读写txt文件 json文件的实现方法
2016/10/22 Python
读取本地json文件,解析json(实例讲解)
2017/12/06 Python
python实现日常记账本小程序
2018/03/10 Python
Python Pandas批量读取csv文件到dataframe的方法
2018/10/08 Python
对Python中内置异常层次结构详解
2018/10/18 Python
关于pytorch中全连接神经网络搭建两种模式详解
2020/01/14 Python
Python基于class()实现面向对象原理详解
2020/03/26 Python
html5 touch事件实现触屏页面上下滑动(二)
2016/03/10 HTML / CSS
美国牛仔品牌:True Religion
2018/11/16 全球购物
自我鉴定范文
2013/11/10 职场文书
简短的公司员工自我评价分享
2013/11/13 职场文书
售后服务经理岗位职责范本
2014/02/22 职场文书
勾股定理课后反思
2014/04/26 职场文书
十佳护士先进事迹
2014/05/08 职场文书
就业协议书怎么填
2014/09/15 职场文书
旅游局领导班子“四风”问题对照检查材料思想汇报
2014/09/29 职场文书
环卫工作汇报材料
2014/10/28 职场文书
金砖之国观后感
2015/06/11 职场文书
如何判断微信付款码和支付宝付款码
2021/04/01 PHP
springboot如何初始化执行sql语句
2021/06/22 Java/Android
Elasticsearch Recovery 详细介绍
2022/04/19 Java/Android