I have a dataframe and I want to match it with another one and do some calculation in pyspark. for example:
# the data to calculate
from pyspark.sql import SparkSession
spk = SparkSession.builder.appName("dataFrame").getOrCreate()
df = spk.createDataFrame([
("Hi I heard about Spark".split(" "), ),
([],),
("I wish Java could use case classes".split(" "), ),
("Logistic regression models are neat".split(" "), ),
("",)
], ["text"])
The other dataframe was obtained by word2vec, it was like this:
# the dic
df_vec = spk.createDataFrame([("I", [0.1, 0.6, -0.2]),
("have", [0.3, -0.1, 0.2]),
("could ", [-0.4, 0.1, -0.8]),
("case", [-0.1, 0.9, 0.6]),
("are", [0.5, -0.3, -0.2])], ["word", "vector"])
I want to get the value of each row of df by matching df_vec, and calculate the average.
I have tried the following code:
from pyspark.sql.functions import when
import pyspark.sql.functions as F
def get_vector(s_list):
final = []
for i in range(len(s_list)):
res = []
if len(s_list[i]) >= 2:
for j in range(len(s_list[i])):
d1 = df_vec.filter(df_vec.word == s_list[i][j]).select('vector')
res1 = d1.rdd.map(lambda row: row["vector"]).collect()
res.append(res1[0])
res2 = spk.createDataFrame(res, ['v1', 'v2', 'v3'])
df_agg = res2.agg(F.avg(res2.v1), F.avg(res2.v2), F.avg(res2.v3))
df_agg = df_agg.rdd.flatMap(lambda x: x).collect()
else:
df_agg = [0,0,0]
# print(i)
final.append(df_agg)
return final
# get vector
get_vector(df.select("text").collect())
It worked but imagining the dataFrame I have is too big to use the collect(), so the fuction get_vector does not work anymore. Do you have any advice? Thanks!