在PySpark数据框中添加列需要花费时间

时间:2019-06-06 12:22:41

标签: python dataframe pyspark apache-spark-sql

我目前正在尝试将PySpark和Cassandra集成在一起,并且在优化代码以使其更快执行方面遇到困难。

from pyspark import SparkContext, SparkConf
from pyspark.sql import SQLContext, SparkSession
from pyspark.sql.functions import sum as _sum

def connect_cassandra():
    spark = SparkSession.builder \
      .appName('SparkCassandraApp') \
      .config('spark.cassandra.connection.host', 'localhost') \
      .config('spark.cassandra.connection.port', '9042') \
      .config('spark.cassandra.output.consistency.level','ONE') \
      .master('local[*]') \
      .getOrCreate()

    sqlContext = SQLContext(spark)
    return sqlContext

#--------THIS FUNCTION IS MY CONCERN ACTUALLY------------
def check_ip(ip, df):
    rows= df.filter("src_ip = '"+ip+"' or dst_ip = '"+ip+"'") \
            .agg(_sum('total').alias('data')) \
            .collect()

    print(rows[0][0])
#-----------------------------------------------------------

def load_df(sqlContext):

    df = sqlContext \
      .read \
      .format('org.apache.spark.sql.cassandra') \
      .options(table='acrs_app_data_usage', keyspace='acrs') \
      .load()

    return df

if __name__ == '__main__':
    lists = ['10.8.25.6', '10.8.24.10', '10.8.24.11', '10.8.20.1', '10.8.25.15', '10.8.25.10']
    sqlContext = connect_cassandra()
    df = load_df(sqlContext)
    for ip in lists:
        check_ip(ip, df)

这里的函数check_ip()带有一个ip和一个预加载的数据帧,该数据帧有3列(src_ip, dst_ip and total)和大约250K行,作为参数,然后遍历它的总列添加它们并返回按提供的IP分组的汇总数据。

但是,当我执行脚本时,每个IP至少要花一秒钟的时间才能返回总和。我有超过32K个IP必须相同。而且时间很长。

任何帮助将不胜感激。预先感谢。

1 个答案:

答案 0 :(得分:1)

简短的回答:不要使用循环。

可能的解决方案:

  • lists转换为数据框。
  • lists_df进行数据框内部联接两次,第一次在ip == src_ip上,第二次在ip == dst_ip
  • 同时与unionAll
  • 串联
  • 最后使用groupBy("ip").agg(_sum("total"))

这使用联接。因此,也许有一个更好的解决方案。