- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-28-2021 06:18 AM
@Dan Zafar do you have any ideas on how would I optimize the query that requires an access to a class method? Details below.
I created a class ProtoFetcher that hosts various proto_pb2.py files create using protoc.tools (similarly as in the original post). It can be instantiated by giving a name of the data; internally it imports the correct some_proto_pb2 class, assigns it to class variables and uses the get_attr("some_proto_pb2", "name_of_this_message") to fetch the correct GeneratedProtocolMessageType (which is defined in google.protobuf.pyext.cpp_message).
Sadly, I can't seem to find a way to use the UDF so that the class initialisation wouldn't be inside the function. If I'm not completely wrong, this means that the class will get initialised for each row as a loop. Trying to access the method from outside the udf definition will raise a "PicklingError: Could not serialize object: TypeError: cannot pickle 'google.protobuf.pyext._message.MessageDescriptor' object"
@udf("string")
def my_test_func(blob):
d = ProtoFetcher("name_of_this_data")
return d.blob_to_json(blob)
new_df = df.withColumn("blob_as_json", my_test_func("original_blob_col"))Running a display() on that new_df takes about 40 seconds, and this test file has only 600 rows. I also tried the pandas_udf approch and got the similar results. I defined the pandas_udf as:
@pandas_udf("string")
def my_test_function(s: pd.Series) -> pd.Series:
d = ProtoFetcher("name_of_this_data")
s_json = s.apply(d.blob_to_json)
return s_jsonNOTE: The blob column has a fair amount of data, though. Running the same code using local Pandas installation will take 32 seconds on a fairly powerful laptop. This was being run with a code:
df['new_col'] = df['original_col'].apply(d.blob_to_json)