我正在尝试这样做:
我的代码如下。我从表1中获取值,并将其传递给UDF。使用该值,我希望能够过滤另一个UDF以返回会话号。
当我收到此错误消息时,此方法无效。
pickle.PicklingError: Could not serialize object: Py4JError: An error occurred while calling o73.__getnewargs__. Trace:
py4j.Py4JException: Method __getnewargs__([]) does not exist
为什么会这样?
dpi_data = spark_session.sql("Select *, ((time_hour*3600) + (time_minute *60) + time_second) as seconds from table1 where hour = 04 and dt = " + yday_date )
dpi_sessions = spark_session.sql("select *, lead(seconds,1) over(partition by user order by seconds) as end_time from (select user, apn, ((time_hour*3600) + (time_minute *60) + time_second) as seconds from table2 where hour = 04 and dt = " + yday_date + ")x" )
def getsession(seconds):
output = dpi_sessions.filter((dpi_sessions.start_time <= seconds) & (dpi_sessions.end_time >= seconds))
print(output)
return 'sss'
myudf = udf(getsession, StringType())
dpi_data = dpi_data.withColumn('apn', myudf(dpi_data.seconds))
输入为:表1
因此,在这里,我们将用户匹配到正确的会话。表1中的时间戳记在表2的开始时间与结束时间之间。
答案 0 :(得分:1)
我认为您使用的UDF错误。您不能一次处理特定行中的列值,而不能在其他地方引用另一个DataFrame。
我认为,解决您的问题的方法是,您必须拥有join
个表,然后检查哪个seconds
属于哪个会话(发生在start
和{{1}之间) }。
让我们看一遍。
end
到目前为止很好。现在我们只需加入即可。
# We set up the problem
# First DataFrame
dpi_data_columns = ["user", "seconds"]
data1 = [(272927, 31924), (272927, 32000), (272927, 45000), (272927, 78000), (272927, 79000)]
dpi_data_rdd = spark.sparkContext.parallelize(data1)
# We rename user to user1 because to avoid column name duplicates post join
dpi_data = dpi_data_rdd.toDF(dpi_data_columns).withColumnRenamed("user", "user1")
dpi_data.show()
#+------+-------+
#| user1|seconds|
#+------+-------+
#|272927| 31924|
#|272927| 32000|
#|272927| 45000|
#|272927| 78000|
#|272927| 79000|
#+------+-------+
# First DataFrame
dpi_sessions_columns = ["user", "start", "end", "key"]
data2 = [(272927, 15000, 40000, "Paid"), (272927, 40001, 86000, "Unpaid")]
dpi_sessions_rdd = spark.sparkContext.parallelize(data2)
# We rename user to user2 because to avoid column name duplicates post join
dpi_sessions = dpi_sessions_rdd.toDF(dpi_sessions_columns).withColumnRenamed("user", "user2")
dpi_sessions.show()
#+------+-----+-----+------+
#| user2|start| end| key|
#+------+-----+-----+------+
#|272927|15000|40000| Paid|
#|272927|40001|86000|Unpaid|
#+------+-----+-----+------+
这就是您想要的输出,不需要UDF。