在spark中,对数据的查询和数据库是有点对其的,有条件查询也有全量查询
头文件导入和测试数据创建具体如何创建原始数据,请看上一篇博客(dataframe的8种创建方法)
from pyspark.sql import SparkSession spark = SparkSession.builder.appName('increase delete change select').master('local').getOrCreate()
df = spark.createDataframe([ ['alex',1,2,'string1'], ['paul',11 ,12,'string2'], ['alex',21,22,'leon'], ['james',31,32,'traveler']],schema=('name string,a long, b long, c string'))
df.show()
+-----+---+---+--------+ | name| a| b| c| +-----+---+---+--------+ | alex| 1| 2| string1| | paul| 11| 12| string2| | alex| 21| 22| leon| |james| 31| 32|traveler| +-----+---+---+--------+条件查询
对数据的条件查询其实是针对具体的列进行 *** 作的,所以可以认为每一次的条件查询,都是要把条件施加到具体的某一列上,比如df.filter(df.age > 10),这个大于10的条件诗选就是实在具体的age列上的。
条件查询用filter,具体的格式如下:
df[‘筛选条件’]
df.filter(‘筛选条件’)
df.where(‘筛选条件’)
二者的用法一样,所以二选一讲解即可
1.1.在区间查询上,通常最常规的当让是可以利用关系运算符进行查询(> , < , == )
下图是筛选所有记录中,a列中大于20的数据记录
#这是利用关系运算符进行查询的,< 和 ==的查询类似 df.filter(df.a > 20).show()
+-----+---+---+--------+ | name| a| b| c| +-----+---+---+--------+ | alex| 21| 22| leon| |james| 31| 32|traveler| +-----+---+---+--------+
df[df.a > 20].show()
+-----+---+---+--------+ | name| a| b| c| +-----+---+---+--------+ | alex| 21| 22| leon| |james| 31| 32|traveler| +-----+---+---+--------+
1.2,between(lowerBound, upperBound)
查询最低值lowerBound到最高值upperBound之间的数据记录
下图是筛选所有记录中,a列中数据在10-30之间的数据记录
df.filter(df.a.between(10,30)).show()
+----+---+---+-------+ |name| a| b| c| +----+---+---+-------+ |paul| 11| 12|string2| |alex| 21| 22| leon| +----+---+---+-------+2.子串的包含查询
2.1 contains(other)
查询包含子串other的数据记录,通常这个other是一个字符串
下图是筛选所有记录中,c列值包含str的数据记录
值得注意的是:这个作为一个字串,在实际的查询的字符串中,它可以是任何位置,比如有一个之是string1,这里的other如果是in,那他会在string1中每一个位置搜寻in,找到就可
df.filter(df.c.contains('str')).show()
+----+---+---+-------+ |name| a| b| c| +----+---+---+-------+ |alex| 1| 2|string1| |paul| 11| 12|string2| +----+---+---+-------+
2.2 like(str)
查询满足str条件的数据,通常这个str是一个由字符串和通配符组成的
下图是筛选所有记录中,c列值以on结尾的数据记录
值得注意是:这个on的位置是固定,必须是在尾部,因为前面有一个on的通配符,如果是on%,那on必须在开头,所以这个on的位置是由我们自己设定的,这点是和contains不同之处
df.filter(df.c.like('%on')).show()
+----+---+---+----+ |name| a| b| c| +----+---+---+----+ |alex| 21| 22|leon| +----+---+---+----+
2.3 startswith(other)
查询数据是以other开头的数据记录
下图是筛选所有记录中,c列值以str开头的数据记录
注意:这里其实好比是contains和like的特殊形式
df.filter(df.c.startswith('str')).show()
+----+---+---+-------+ |name| a| b| c| +----+---+---+-------+ |alex| 1| 2|string1| |paul| 11| 12|string2| +----+---+---+-------+
2.4 endswith(other)
查询数据是以other结尾的数据记录
下图是筛选所有记录中,c列值以ing2结尾的数据记录
注意:这里其实好比是contains和like的特殊形式
df.filter(df.c.endswith('ing2')).show()
+----+---+---+-------+ |name| a| b| c| +----+---+---+-------+ |paul| 11| 12|string2| +----+---+---+-------+
2.5.isin(*cols)
查询具体列中,包含在cols下的数据,通常这可以叫具体查询
下图是筛选所有记录中,c列值为string1和Leon的数据记录
df.filter(df.c.isin(['string1','leon'])).show()
+----+---+---+-------+ |name| a| b| c| +----+---+---+-------+ |alex| 1| 2|string1| |alex| 21| 22| leon| +----+---+---+-------+3.空值查询
3.1.isNotNull()
列中非空值筛选
下图是筛选所有记录中,a不为0的数据记录。
df.filter(df.a.isNotNull()).show()
+-----+---+---+--------+ | name| a| b| c| +-----+---+---+--------+ | alex| 1| 2| string1| | paul| 11| 12| string2| | alex| 21| 22| leon| |james| 31| 32|traveler| +-----+---+---+--------+
3.2.isNull()
列中空值筛选
下图是筛选所有记录中,a为0的数据记录。
df.filter(df.a.isNull()).show()
+----+---+---+---+ |name| a| b| c| +----+---+---+---+ +----+---+---+---+全量查询
具体格式如下:
df.select(要显示的列)
df[要显示的列]
1.1第一种查询,用’.'来表示列
下图是查询a列和c列
df.select(df.a,df.c).show()
+---+--------+ | a| c| +---+--------+ | 1| string1| | 11| string2| | 21| leon| | 31|traveler| +---+--------+
1.2.第二种查询,用[]来表示列
下图是查询a列和c列
df.select(df['a'],df['c']).show()
+---+--------+ | a| c| +---+--------+ | 1| string1| | 11| string2| | 21| leon| | 31|traveler| +---+--------+2.[ ]全量查询
同样的,对于这样的方式,你可以有三种写法:
第一种就是利用’.‘来访问列,比如:df[ df.a,df.c ]
第二种就是利用[]来访问列,比如:df[ df[‘a’] , df[‘c’] ]
第三种就是利用’.'来访问列,比如:df[ ‘a’,‘c’ ]
下图是查询a列和c列
df[[df.a,df.c]]
Dataframe[a: bigint, c: string]
#3.全量查询的第三种表达 df['a','c'].show()
+---+--------+ | a| c| +---+--------+ | 1| string1| | 11| string2| | 21| leon| | 31|traveler| +---+--------+3.全量查询+条件
全量查询也可以加筛选条件,但是和条件查询的差异在于,它不会将不符合条件的值筛选掉,而是会将施加筛选条件的那一列二值化,不符合条件的为false,符合条件的为true
df.select(df.a,df.b> 20 ).show()
+---+--------+ | a|(b > 20)| +---+--------+ | 1| false| | 11| false| | 21| true| | 31| true| +---+--------+全量查询+替换
接着上面的说,上面的例子可以将符合条件的变为true,不符合的变为false,那具体的应用场景是什么呢?
我们还能做些什么呢?,我们可以进行批量改写,这时候就引出一个when…otherwise()
这个when的api是在functions下,若以需要进行额外的引入
下图是将b列中,大于20的改为888,否则就为999
from pyspark.sql import functions as F df.select(df.a,F.when(df.b > 20, 888).otherwise(999)).show()
+---+----------------------------------------+ | a|CASE WHEN (b > 20) THEN 888 ELSE 999 END| +---+----------------------------------------+ | 1| 999| | 11| 999| | 21| 888| | 31| 888| +---+----------------------------------------+
下图是将b列中,大于20的改为888,小于10的改为666,否则就为999
df.select(df.a,F.when(df.b > 20, 888).when(df.b < 10,666).otherwise(999)).show()
+---+---------------------------------------------------------------+ | a|CASE WHEN (b > 20) THEN 888 WHEN (b < 10) THEN 666 ELSE 999 END| +---+---------------------------------------------------------------+ | 1| 666| | 11| 999| | 21| 888| | 31| 888| +---+---------------------------------------------------------------+列名重命名
从以上的几个例子发现施加条件筛选后的列名奇奇怪怪,很长,这显然不是我们想要的,zip时候可以对其进行列名的修改,将其改为原来的列名
.alias(‘列名’)
.name(‘列名’)
下面举个例子:
未改列名之前,列名很长
df.select(df.a,F.when(df.b > 20, 888).when(df.b < 10,666).otherwise(999)).show()
+---+---------------------------------------------------------------+ | a|CASE WHEN (b > 20) THEN 888 WHEN (b < 10) THEN 666 ELSE 999 END| +---+---------------------------------------------------------------+ | 1| 666| | 11| 999| | 21| 888| | 31| 888| +---+---------------------------------------------------------------+
修改列名后
df.select(df.a,F.when(df.b > 20, 888).when(df.b < 10,666).otherwise(999).alias('b')).show()
+---+---+ | a| b| +---+---+ | 1|666| | 11|999| | 21|888| | 31|888| +---+---+
df.select(df.a,F.when(df.b > 20, 888).when(df.b < 10,666).otherwise(999).name('b')).show()
+---+---+ | a| b| +---+---+ | 1|666| | 11|999| | 21|888| | 31|888| +---+---+数据类型修改
有时候想对数据进行类型转换,比如将某一列的bingint型转为string类型这样,可以有两种方法。
一种方法是astype();
一种方法是case();
二者的用法是完全一致的
df
Dataframe[name: string, a: bigint, b: bigint, c: string]
df[df.a,df.b.astype('string'),df.c]
Dataframe[a: bigint, b: string, c: string]
df[df.a.cast('string'),df.b.astype('string'),df.c]
Dataframe[a: string, b: string, c: string]
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)