spark RDD的学习,filter函数的学习,split函数的学习

spark RDD的学习,filter函数的学习,split函数的学习_第1张图片
参考https://blog.csdn.net/xufangfang5206/article/details/80030300
https://www.cnblogs.com/ruoniao/p/6869319.html
split是可以用多种不同的符号(转义字符,以及标点符号)作为分隔符的!!!
(1)读取txt文件,按\t分隔,将分割出来的列大于指定列的滤掉,解析不准;
注意len的用法

 self.df_judgedoc_info_sample = self.session.read.text(self.judgedoc_info_sample_table_input)

        self.df_judgedoc_info_sample = self.df_judgedoc_info_sample.rdd \
                .filter(lambda line: len((line["value"] or "").split('\t')) == 6)\
            .map(lambda line: Row(**dict(zip(raw_judgedoc_info_field, line["value"].split('\t')))))\
                .toDF()
(a) 注意此处len的写法,为了避免有的时候变量为空,需增加一个 or '' ,构成逻辑变量,为空会自动取 '' ,len('')为0,这样就不会报错;
In[38]: len('哈哈' or '')
Out[38]: 6
In[39]: len( None or '')
Out[39]: 0
In[40]: len( None)
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/IPython/core/interactiveshell.py", line 2820, in run_code
    exec code_obj in self.user_global_ns, self.user_ns
  File "", line 1, in 
    len( None)
TypeError: object of type 'NoneType' has no len()

(b)filter(lambda line: len((line["value"] or "").split('\t'))== 6)

结构解读顺序:
首先:(line["value"] or "").split('\t') 
先取line中的value字段列,spark读txt文件的时候默认的列是value命名的,txt存文件是一行一行地存,默认不分列,因此,当存一些包含汉字字段的时候,不需要像csv一样把一行还要解析成多列,有时候解析不准,会出现IndexOutBound,索引越界的错误,即误解析了无穷列,超出了spark处理列的范围;因此可以用txt保存,然后用读txt的方式处理字段;取split

用\t划分
In[56]: u'哈哈 你好   哼哼'.split(u'\t')
Out[56]: [u'\u54c8\u54c8 \u4f60\u597d   \u54fc\u54fc']

用空格划分
In[57]: u'哈哈 你好   哼哼'.split(u' ')
Out[57]: [u'\u54c8\u54c8', u'\u4f60\u597d', u'', u'', u'\u54fc\u54fc']


In[51]: S = "this is string example....wow!!!"
In[52]: print (S.split( ))
['this', 'is', 'string', 'example....wow!!!']
In[53]: print (S.split('i',1))
['th', 's is string example....wow!!!']
In[54]: print (S.split('w'))
['this is string example....', 'o', '!!!']
In[55]: '哈哈 你好   哼哼'.split(u'\t')

str = "Line1-abcdef \nLine2-abc \nLine4-abcd";
print str.split( );
print str.split(' ', 1 );
结果:
['Line1-abcdef', 'Line2-abc', 'Line4-abcd']
['Line1-abcdef', '\nLine2-abc \nLine4-abcd']
上式中1为分隔次数;split还可以指定分隔次数;

split('符号'),其作用就是,找到字符串中该符号的位置,在该符号的位置加上 ',' 这样就达到用以分隔前后字符的目的, 然后删除该符号本身!!!!
然后:
理解filter的作用:
filter本质是作用一个bool值,即里面的函数返回的是一个bool变量:
filter(lambda line: len((line["value"] or "").split('\t'))== 6) 正确
里面的lambda line: len((line["value"] or "").split('\t'))== 6 ,判断列数为6返回true,否则返回False;

错误写法:
filter(lambda line: line.split('\t') if len(line.split('\t')) <7 else None) 
这会出现两个bug:第一),line为空;第二)lambda函数返回的有None值不为TrueFalse,filter只接受true和False

字符串的分隔

字符串的切割    
 当需要的分隔符是一个是:
    s.split("分隔符")
    当分隔符是多个时:
    s = "abcd,1313|;gg2*hhh"
    方法一:
        将多个分隔符每个每个的拆开分隔
    方法二:
        通过re模块的split()方法
方法一:
 1 def mySplit(s,ds):
 2     res =[s]
 3     for d in ds:
 4         t =[]
 5         map(lambda x:t.extend(x.split(d)),res)
 6         res = t
 7     #当s中存在连续的分隔符时,就会出现空格的,下面是去除空格
 8     return [x for x in res if x]
 9 s = "abcd,1313|;gg2*hhh"
10 res = ',|;*'
11 print(mySplit(s,res))

方法二:
1 In [9]: s = "abcd,1313|;gg2*hhh"
2 
3 In [10]: import re
4 
5 In [11]: re.split('[,|;*]+',s)   #正则表达式[,|;*]中的任何一个出现至少一次
6 Out[11]: ['abcd', '1313', 'gg2', 'hhh']

注意map的用法
dfrdd = df.map(mapper)
dfrdd = df.map(lambda line:mapper(line))

sqlContext = SQLContext(sparkContext=sc)
    df = sqlContext.read.text(hdfspath)
    dfrdd = df.map(mapper)
 此处df的结构为'pyspark.rdd.RDD'>
有的时候,map需要写lambda,有的时候不需要,依据是判断当前函数的输入是不是可以直接用rdd的结构进行输入,rdd的结构与
dfrdd = df.map(mapper)
print(type(dfrdd))   #



Dataframe转RDD
RDD.map(func)
RDD.map(lambda x : func(x))  
上面两个的区别;数据结构不一样?????
piplineRDD has no map

数值和键值对RDD
数字类型的RDD支持统计型函数操作,而键值对形式的RDD诸如根据键聚合的数据的键值对操作
把一个普通的RDD转化为pairRDD,可调用map函数实现,pairRDD

ps aux | grep spark

kill 155286
RDD is empty filter本来

你可能感兴趣的:(python,spark海量数据分析)