Repository: modin-project/modin

Issue:
Lambda df.apply issues returning NaN on a column
### System information
MACOS: Python3
using modins latest version `pip install modin`

### Describe the problem
<!-- Describe the problem clearly here. -->
On a column df.apply is returning nan values. 

Check Images below:
![Screenshot 2019-05-13 at 9 53 42 PM](https://user-images.githubusercontent.com/47315683/57638085-a1ce3480-75ca-11e9-8702-401577c1559f.png)
![Screenshot 2019-05-13 at 9 53 17 PM](https://user-images.githubusercontent.com/47315683/57638101-ad216000-75ca-11e9-9877-326026ead85c.png)
![Screenshot 2019-05-13 at 9 52 46 PM](https://user-images.githubusercontent.com/47315683/57638111-b4486e00-75ca-11e9-8596-d59e86fcbe81.png)



Discussion:

Resolving patch:
diff --git a/modin/engines/ray/utils.py b/modin/engines/ray/utils.py
--- a/modin/engines/ray/utils.py
+++ b/modin/engines/ray/utils.py
@@ -11,6 +11,9 @@ def handle_ray_task_error(e):
         if "Error" in s or "Exception" in s:
             try:
                 raise getattr(builtins, s.split(":")[0])("".join(s.split(":")[1:]))
-            except AttributeError:
-                break
+            except AttributeError as att_err:
+                if "module" in str(att_err) and builtins.__name__ in str(att_err):
+                    pass
+                else:
+                    raise att_err
     raise e
diff --git a/modin/pandas/dataframe.py b/modin/pandas/dataframe.py
--- a/modin/pandas/dataframe.py
+++ b/modin/pandas/dataframe.py
@@ -300,7 +300,7 @@ def apply(
                     result_type=result_type,
                 )
             ).__name__
-        except ValueError:
+        except Exception:
             return_type = self.__name__
         if return_type not in ["DataFrame", "Series"]:
             return query_compiler.to_pandas().squeeze()
diff --git a/modin/pandas/series.py b/modin/pandas/series.py
--- a/modin/pandas/series.py
+++ b/modin/pandas/series.py
@@ -376,11 +376,16 @@ def apply(self, func, convert_dtype=True, args=(), **kwds):
         # a list or a dictionary, which means that the return type won't change from
         # type(self), so we catch that error and use `self.__name__` for the return
         # type.
-        return_type = type(
-            getattr(getattr(pandas, self.__name__)(index=self.index), apply_func)(
-                func, *args, **kwds
-            )
-        ).__name__
+        # Because a `Series` cannot be empty in pandas, we create a "dummy" `Series` to
+        # do the error checking and determining the return type.
+        try:
+            return_type = type(
+                getattr(pandas.Series([""], index=self.index[:1]), apply_func)(
+                    func, *args, **kwds
+                )
+            ).__name__
+        except Exception:
+            return_type = self.__name__
         if (
             isinstance(func, string_types)
             or is_list_like(func)


Test patch:
diff --git a/modin/pandas/test/test_series.py b/modin/pandas/test/test_series.py
--- a/modin/pandas/test/test_series.py
+++ b/modin/pandas/test/test_series.py
@@ -4,6 +4,7 @@
 
 import pytest
 import numpy as np
+import json
 import pandas
 import matplotlib
 import modin.pandas as pd
@@ -480,7 +481,7 @@ def test_agg(data, func):
         pandas_result = pandas_series.agg(func)
     except Exception as e:
         with pytest.raises(type(e)):
-            modin_series.agg(func)
+            repr(modin_series.agg(func))
     else:
         modin_result = modin_series.agg(func)
         df_equals(modin_result, pandas_result)
@@ -513,7 +514,7 @@ def test_aggregate(request, data, func):
         pandas_result = pandas_series.aggregate(func, axis)
     except Exception as e:
         with pytest.raises(type(e)):
-            modin_series.aggregate(func, axis)
+            repr(modin_series.aggregate(func, axis))
     else:
         modin_result = modin_series.aggregate(func, axis)
         df_equals(modin_result, pandas_result)
@@ -650,12 +651,32 @@ def test_apply(request, data, func):
         pandas_result = pandas_series.apply(func)
     except Exception as e:
         with pytest.raises(type(e)):
-            modin_series.apply(func)
+            repr(modin_series.apply(func))
     else:
         modin_result = modin_series.apply(func)
         df_equals(modin_result, pandas_result)
 
 
+def test_apply_external_lib():
+    json_string = """
+    {
+        "researcher": {
+            "name": "Ford Prefect",
+            "species": "Betelgeusian",
+            "relatives": [
+                {
+                    "name": "Zaphod Beeblebrox",
+                    "species": "Betelgeusian"
+                }
+            ]
+        }
+    }
+    """
+    modin_result = pd.DataFrame.from_dict({"a": [json_string]}).a.apply(json.loads)
+    pandas_result = pandas.DataFrame.from_dict({"a": [json_string]}).a.apply(json.loads)
+    df_equals(modin_result, pandas_result)
+
+
 @pytest.mark.parametrize("data", test_data_values, ids=test_data_keys)
 @pytest.mark.parametrize("func", agg_func_values, ids=agg_func_keys)
 def test_apply_numeric(request, data, func):
@@ -666,7 +687,7 @@ def test_apply_numeric(request, data, func):
             pandas_result = pandas_series.apply(func)
         except Exception as e:
             with pytest.raises(type(e)):
-                modin_series.apply(func)
+                repr(modin_series.apply(func))
         else:
             modin_result = modin_series.apply(func)
             df_equals(modin_result, pandas_result)
@@ -2471,7 +2492,7 @@ def test_transform(data, func):
         pandas_result = pandas_series.transform(func)
     except Exception as e:
         with pytest.raises(type(e)):
-            modin_series.transform(func)
+            repr(modin_series.transform(func))
     else:
         df_equals(modin_series.transform(func), pandas_result)