Pyspark rdd 和 dataframe 使用

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”) 把第一行列名作为数据记录
  • 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())
      按照这两列进行升序排序;先找第一列进行排序,第一列内容相同情况下,在按照第二列进行排序
  • 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") 存储数据小于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如何使用

你可能感兴趣的:(python,python,spark,大数据)