Оператор ==
проверяет, указывают ли две ссылки на один и тот же объект или нет. .equals()
проверьте фактическое содержимое строки (значение).
Обратите внимание, что метод .equals()
принадлежит классу Object
(суперкласс всех классов). Вам необходимо переопределить его в соответствии с вашим требованием к классу, но для String оно уже реализовано и проверяет, имеет ли две строки одно и то же значение.
String s1 = "Stack Overflow";
String s2 = "Stack Overflow";
s1 == s2; //true
s1.equals(s2); //true
Причина: строка литералы, созданные без нуля, хранятся в пуле строк в области перментонов кучи. Таким образом, оба s1 и s2 указывают на один и тот же объект в пуле. String s1 = new String("Stack Overflow");
String s2 = new String("Stack Overflow");
s1 == s2; //false
s1.equals(s2); //true
Причина. Если вы создаете объект String с использованием ключевого слова new
, ему выделяется отдельное пространство в куче. Источником проблемы является то, что объект, возвращаемый из UDF, не соответствует объявленному типу. np.unique
не только возвращает numpy.ndarray
, но и преобразует числовые значения в соответствующие NumPy
типы , которые не совместимы с DataFrame
API. Вы можете попробовать что-то вроде этого:
udf(lambda x: list(set(x)), ArrayType(IntegerType()))
или это (чтобы сохранить порядок)
udf(lambda xs: list(OrderedDict((x, None) for x in xs)),
ArrayType(IntegerType()))
.
Если вы действительно хотите np.unique
вам нужно преобразовать вывод:
udf(lambda x: np.unique(x).tolist(), ArrayType(IntegerType()))
Вам нужно преобразовать конечное значение в список python. Вы реализуете функцию следующим образом:
def uniq_array(col_array):
x = np.unique(col_array)
return list(x)
Это происходит потому, что Spark не понимает формат массива numpy. Чтобы передать объект python, который Spark DataFrames понимает как ArrayType
, перед его возвратом вам нужно преобразовать вывод в python list
.