PySpark rdd 使用
- mapValuese(list)
Pass each value in the key-value pair RDD through a map function
without changing the keys; this also retains the original RDD’s partitioning.
demo:rdd.map(lambda x: (x[0], x)).groupByKey().mapValues(list).collect() - orderRDD.union(sc.parallelize([[11111111, 111111, 11111, 111, 0]]))
Return the union of this RDD and another one. - orderRDD.zipWithIndex()
Zips this RDD with its element indices. - cRDD.join(fRDD)
Return an RDD containing all pairs of elements with matching keys in
C{self} and C{other}
pyspark dataframe
- 0.读取csv文件 spark.read.csv()
- demo:df = spark.read.csv(“G:\测试数据\shanghaiNeiheSplit.csv”)
df 数据类型 pyspark dataframe - 如果输入文件有列名, df2=spark.read.option(“header”,True).csv(“zipcodes.csv”) 把第一行列名作为数据记录
- demo:df = spark.read.csv(“G:\测试数据\shanghaiNeiheSplit.csv”)
- 1.设置临时文件目录 config(“spark.local.dir”, “F:\spark-temp”)
- 2.按照某列进行分组,并对每组进行处理,处理方法:通过自定义的方法 udf
* df.groupby([column1]).apply(udf)
udf 输入输出均为pandas.DataFrame
demo:selectMMSI = df.groupby(["_c0"]).apply(subtract_mean)
ls = [StructField('mmsi', LongType(), True), StructField('timestamp', DoubleType(), True),
StructField('latitude', DoubleType(), True), StructField('longitude', IntegerType(), True)]
@pandas_udf(StructType(ls), PandasUDFType.GROUPED_MAP)
def subtract_mean(df): # Input/output are both a pandas.DataFrame
print(type(df))
return pd.DataFrame(df, columns=["mmsi", "timestamp", "latitude", "longitude"])
- udf各个进程文件合并在一起时候出现的问题;
需要看文件进行合并时是什么地方出现问题;到底是开始时出现问题,还是后面出现问题;开始时出现问题,两个进程数据合并出现问题,即两两进程之间数据格式不一致;
文件不能合并成功:就是读取的文件格式和文件输出的格式不一致;
可能出问题地方:每列的字段名以及每列的数据格式 - 创建UDF有两种方法;一种是把function转化为udf;一种是通过注解方式转化为udf
- 2.pyspark dataframe 取某几列数据
df.select(“firstname”,“lastname”)
demo:specificDf = df.select("_c0", “_c1”, “_c6”, “_c7”)
pyspark dataframe df 取 “_c0”, “_c1”, “_c6”, “_c7” 这四列数据 - 3.pyspark 广播变量 广播变量是在机群中各个executor中的只读变量;
broadcastStates = spark.sparkContext.broadcast(states)
broadcastStates.value
demo:
mmsi = [205451006, 249451001, 431305000, 168808, 98336057]
broadcastProperty = spark.sparkContext.broadcast(mmsi)
在task中获取广播变量
broadcastValues = broadcastProperty.value
-
4.pyspark dataframe 增加一列数据,并对每列数据进行udf operation areaTrack.withColumn(“column2”,udf)
-
df=df.withColumn(“areaID”,eachrowIsInPolygon(areaTrack.latitude, areaTrack.longitude))
-
withColumn(colName,col) Returns a new :class:
DataFrame
by adding a column or replacing the existing column that has the same name. -
demo: areaTrack 新增一列 areaID,对每列数据的经纬度坐标判断属于哪个多边形内
areaTrack = areaTrack.repartition(1).withColumn(“areaID”,
eachrowIsInPolygon(areaTrack.latitude, areaTrack.longitude))@F.udf(returnType=IntegerType())
def eachrowIsInPolygon(latitude, longitude):
‘’’
RDD 每行数据判断是否在多边形内
:return:
‘’’
# print(row)
try:
lat = latitude / 1e6
lon = longitude / 1e6
# print(lat, lon)
area = AreaProperty.value
# print(area)
l = 1 # 标记属于哪个多边形
for label, a in area.items():
if label.find(“shanghai”) != -1:
label = 2 # 上海内areaID 为2
elif label.find(“jiangsu”) != -1:
label = 3 # 江苏内areaID 为3
isIn = point_poly(lon, lat, a)
# print(isIn)
if isIn:
l = label
return l
except:
return 1
-
-
5.筛选 filter 根据给定的SQL表达式对RDD/DataFrame 行进行筛选 filter
- 单个条件 df=df.filter(df.state==“OH”) 筛选state列等于 OH的所有行数据
- 多个条件 df=df.filter( (df.state==“OH”) & (df.gender==“M”))
两列都满足条件的所有行数据
-
6.排序 按照某列进行 升序 或者 降序 排序 orderBy() sort() asc升序排序
- df=df.sort(df.department.asc(),df.state.asc())
按照这两列进行升序排序;先找第一列进行排序,第一列内容相同情况下,在按照第二列进行排序
- df=df.sort(df.department.asc(),df.state.asc())
-
7.分区 repartition
在dataframe上调用groupBy()、groupByKey()、reduceByKey()、
join()等相似功能,会在多个spark executors和机器上shuffling 数据,最后会默认把数据重新分区到200个分区。
df4 = df.groupBy(“id”).count()
print(df4.rdd.getNumPartitions())
df4默认分区数是200 -
8.选择一列或多列 select()
- select() pyspark transformation 算子,并返回一个包含选择列的新dataframe
- demo1:df.select(“firstname”) df.select(“firstname”,“lastname”)
- demo2:specificDf = df.select(df[’_c0’].cast(‘long’).alias(‘mmsi’))
选择 df 的 _c0 列,列名重命名mmsi,同时该列数据类型转变为long
-
9.groupby([“column”]).apply(udf) 对分组数据中的其他字段进行操作,以list格式把返回结果添加到pyspark dataframe
demo:
areaTrack = specificDf.groupby([“areaID”]).apply(is_Inpolygon)
ls2 = [StructField(‘mmsi’, LongType(), True), StructField(‘acqtime’, LongType(), True),
StructField(‘latitude’, LongType(), True), StructField(‘longitude’, LongType(), True),
StructField(‘areaID’, IntegerType(), True)]
@F.pandas_udf(StructType(ls2), F.PandasUDFType.GROUPED_MAP)
Input/output are both a pandas.DataFrame
def is_Inpolygon(df):
try:
areaID = int(df.iloc[0][“areaID”])broadcastValues = broadcastProperty.value # print(areaID, broadcastValues, areaID in broadcastValues) if areaID in broadcastValues: # 两种数据格式不一致,导致出的问题;必须规定好两种格式 print(len(df), type(df)) # df.columns = ["mmsi", "timestamp", "latitude", "longitude"] # print(df) 为什么 pd.DataFrame([[2, 2, 2, 2]]) 就行,而df就不行 return df else: return pd.DataFrame([[1, 1, 1, 1, 1]]) except: return pd.DataFrame([[1, 1, 1, 1, 1]])
specificDf 按照 areaID 列进行分组,并对每组数据判断是否属于多边形所有areaID内,若是则保存,否则置为[1, 1, 1, 1, 1]
-
10.保存为csv文件 write.csv()
result.repartition(1).write.csv(“queryData9.csv”, sep=’,’, header=True, mode=“overwrite”)
把result重新分区,并写到 queryData9.csv 目录下,
csv文件的分隔符为 ‘,’,
有头文件,
写入方式为:“overwrite” Overwrite existing data. 覆盖已经存在的数据
pyspark dataframe相关使用 教程
https://sparkbyexamples.com/pyspark/
pyspark rdd 相关使用教程
https://www.tutorialspoint.com/pyspark/index.htm
Windows 查看 cpu 个数
cpu-z 查看 cpu 核心数,进程数 进程数 即为:同时几个分布式程序执行
cpu核数、cpu个数 ??
spark 各种算子什么时候需要shuffle,什么时候不需要shuffle
使用pyspark 计算大数据程序;
步骤:1.先找小数据集进行测试 pyspark 程序是否正常执行;
尽量每个udf后,输出每个udf计算中的结果,都保存一次数据;以此来判断到底是哪个环节出现问题。
关键点:确定是什么方向出现问题;然后再补救。
2.然后用大数据进行跑数据
Spark 自定义累加器
定义累加器的类
class StringSetAccmulatorParam(AccumulatorParam):
def zero(self, value): # 每次相加的初始值(另一个初始值)
print(value)
return value
def addInPlace(self, value1, value2):
print(type(value1), type(value2), "------addInPlace")
print(value1, value2, "------addInPlace")
value1.append(value2)
return value1
Result = sc.accumulator(value=[[11111111, 1406247685, 1406247685, ‘beee’]], accum_param=StringSetAccmulatorParam())
Result.add(newLine)
累加变量 executor 更新变量(即worker);Driver 读取变量(master)
共享变量 executor 读取变量;Driver 更新变量
python 连接 zookeeper 框架 kazoo
-
1.连接zookeeper
zk = KazooClient(
hosts=‘192.168.18.208:2181,192.168.18.200:2181,192.168.18.206:2181’
,timeout=10.0 #连接超时时间
# , logger=logging #传一个日志对象进行,方便 输出debug日志
)
zk.start() -
2.创建 节点,添加数据
zk.create("/mmsi/Ttime/node",b"111") 存储数据小于256values=(Ttime).to_bytes(10, byteorder = ‘big’)
zk.create(baseTimePath+"/"+str(fTime),bytes(values)) #存储数据大于 256 -
3.修改数据
zk.set("/mmsi/Ttime/node",b"2222") -
4.读取数据
TtimeNode=zk.exists("/mmsi/Ttime/node") 判断节点是否存在
data,stat=zk.get("/mmsi/Ttime/node")
Ttime2 = int.from_bytes(data, byteorder=‘big’) 读取数据超过 256 -
5.删除节点
zk.delete("/mmsi/Ttime/node") -
6.关闭连接
zk.stop()
zk.close() -
7.监听节点数据变化,并每次变化时,执行指定functions
@zkc.DataWatch(path=nodepath)
def my_watch(data, stat, event):
print(data)
触发情况:该监听器会在第一次启动时会运行,节点数据创建时会触发监听器;节点删除时会触发监听器;节点修改数据时触发监听器
总结知识点,还是尽量以业务场景来介绍。如:读取数据 ,怎么做;也可以介绍某几个API如何使用