* 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"])
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
6.排序 按照某列进行 升序 或者 降序 排序 orderBy() sort() 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()
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.然后用大数据进行跑数据
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 更新变量
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") 存储数据小于256
values=(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如何使用