划分不同DataFrame的两列

时间:2016-06-30 15:51:49

标签: python apache-spark pyspark apache-spark-sql

我正在使用Spark对用户日志文件进行探索性数据分析。我正在做的一项分析是每个主机每天的平均请求。因此,为了计算平均值,我需要将DataFrame的总请求列除以DataFrame的数字唯一Request列。

    <%-- Correct number --%>
    <br/> N.Filas powerList: <ics:listget listname="powerList" fieldname="#numRows"/>

    <%-- Incorrect number (Because constraint haven't effect --%>
    N.Filas aslist: <ics:listget listname="aslist" fieldname="#numRows"/>

这是我用PySpark编写的用来确定平均值的内容。这是我得到的错误日志

total_req_per_day_df = logs_df.select('host',dayofmonth('time').alias('day')).groupby('day').count()

avg_daily_req_per_host_df = total_req_per_day_df.select("day",(total_req_per_day_df["count"] / daily_hosts_df["count"]).alias("count"))

注意:daily_hosts_df和logs_df缓存在内存中。如何划分两个数据帧的计数列?

4 个答案:

答案 0 :(得分:15)

无法从另一个表中引用列。如果您想要合并数据,您必须先join使用与此类似的内容:

from pyspark.sql.functions import col

(total_req_per_day_df.alias("total")
    .join(daily_hosts_df.alias("host"), ["day"])
    .select(col("day"), (col("total.count") / col("host.count")).alias("count")))

答案 1 :(得分:1)

这是来自edX Spark课程作业的问题。既然解决方案已公开,我借此机会分享另一个较慢的解决方案,并询问它的性能是否可以提高还是完全反Spark?

daily_hosts_list = (daily_hosts_df.map(lambda r: (r[0], r[1])).take(30))
days_with_hosts, hosts = zip(*daily_hosts_list)
requests = (total_req_per_day_df.map(lambda r: (r[1])).take(30))
average_requests = [(days_with_hosts[n], float(l)) for n, l in enumerate(list(np.array(requests, dtype=float) / np.array(hosts)))]
avg_daily_req_per_host_df = sqlContext.createDataFrame(average_requests, ('day', 'avg_reqs_per_host_per_day'))

答案 2 :(得分:0)

在列日加入两个数据框,然后选择计数列的日期和比率。

total_req_per_day_df = logs_df.select(dayofmonth('time')
                                      .alias('day')
                                     ).groupBy('day').count()

avg_daily_req_per_host_df = (
  total_req_per_day_df.join(daily_hosts_df, 
                            total_req_per_day_df.day == daily_hosts_df.day
                           )
  .select(daily_hosts_df['day'], 
          (total_req_per_day_df['count']/daily_hosts_df['count'])
           .alias('avg_reqs_per_host_per_day')
          )
  .cache()
)

答案 3 :(得分:0)

解决方案,基于zero323答案,但正确地作为OUTER加入。

avg_daily_req_per_host_df = (
  total_req_per_day_df.join(
      daily_hosts_df, daily_hosts_df['day'] == total_req_per_day_df['day'], 'outer'
  ).select(
      total_req_per_day_df['day'], 
      (total_req_per_day_df['count']/daily_hosts_df['count']).alias('avg_reqs_per_host_per_day')
  )
).cache()

没有&#39;外部&#39; param你丢失了一个数据帧中的数据丢失数据。这对于PySpark Lab2任务并不重要,因为两个数据帧都包含相同的日期。但是可以在另一个任务中造成一些痛苦:)