Ошибка ValueError при возврате pandas DataFrame из процессора Execute Python в RapidMiner Studio - PullRequest
1 голос
/ 21 января 2020

В RapidMiner Studio 9.5.1 после завершения моего сценария python я могу напечатать результирующий кадр данных и увидеть, что он создается, как и ожидалось, с соответствующими столбцами. Процессор quickminer все же не работает с сообщением:

Exception: com.rapidminer.operator.OperatorException
Message: Script terminated abnormally: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Stack trace:
  com.rapidminer.extension.pythonscripting.operator.scripting.AbstractScriptRunner.run(AbstractScriptRunner.java:137)
  com.rapidminer.extension.pythonscripting.operator.scripting.AbstractScriptingLanguageOperator.doWork(AbstractScriptingLanguageOperator.java:210)
  com.rapidminer.extension.pythonscripting.operator.scripting.python.PythonScriptingOperator.doWork(PythonScriptingOperator.java:434)
  com.rapidminer.operator.Operator.execute(Operator.java:1032)
  com.rapidminer.operator.execution.SimpleUnitExecutor.execute(SimpleUnitExecutor.java:77)
  com.rapidminer.operator.ExecutionUnit$2.run(ExecutionUnit.java:812)
  com.rapidminer.operator.ExecutionUnit$2.run(ExecutionUnit.java:807)
  java.security.AccessController.doPrivileged(Native Method)
  com.rapidminer.operator.ExecutionUnit.execute(ExecutionUnit.java:807)
  com.rapidminer.operator.OperatorChain.doWork(OperatorChain.java:423)
  com.rapidminer.operator.Operator.execute(Operator.java:1032)
  com.rapidminer.Process.executeRoot(Process.java:1378)
  com.rapidminer.Process.lambda$executeRootInPool$5(Process.java:1357)
  com.rapidminer.studio.concurrency.internal.AbstractConcurrencyContext$AdaptedCallable.exec(AbstractConcurrencyContext.java:328)
  java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
  java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
  java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
  java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

, не предоставляя никакой другой информации и не ссылаясь на строку в моем коде в сценарии. Я обновил библиотеку numpy на случай, если это была проблема совместимости со старыми версиями, но до сих пор нет решения.

numpy                     1.14.5                   pypi_0    pypi
numpy-base                1.16.4           py36hc3f5095_0    defaults
numpydoc                  0.9.1                      py_0    defaults
pandas                    0.25.3           py36ha925a31_0    defaults

Кроме того, при проверке среды python (Anaconda env), из Настройки> Настройки> Python Сценарии в RapidMiner, все тесты проходят успешно.

Процессор xml из файла .rmp:

  <operator activated="true" class="python_scripting:execute_python" compatibility="9.5.000" expanded="true" height="103" name="Execute Python" width="90" x="313" y="34">
    <parameter key="script" value="import pandas&#10;&#10;# rm_main is a mandatory function, &#10;# the number of arguments has to be the number of input ports (can be none)&#10;def rm_main(data):&#10;    print('Hello, world!')&#10;    # output can be found in Log View&#10;    print(type(data))&#10;&#10;    #your code goes here&#10;&#10;    #for example:&#10;    data2 = pandas.DataFrame([3,5,77,8])&#10;&#10;    # connect 2 output ports to see the results&#10;    return data, data2"/>
    <parameter key="script_file" value="%{ResourcePath}\detect_aggressive_language.py"/>
    <parameter key="notebook_cell_tag_filter" value=""/>
    <parameter key="use_default_python" value="true"/>
    <parameter key="package_manager" value="conda (anaconda)"/>
    <description align="center" color="transparent" colored="false" width="126">Detect Script</description>
  </operator>

До сих пор я попробовал: 1. Обновите исходный DataFrame (данные) с моими вычисленными столбцами и верните его. 2. Создайте новый DataFrame с моими столбцами и верните его как один или как второй аргумент после данных. 3. Создайте метод (внутри сценария), который принимает исходные данные DataFrame в качестве аргумента, изменяет их, а затем возвращает их. 4. Выберите новый DataFrame, сохраните его, загрузите и верните. Все эти попытки привели к одной и той же ошибке, представленной выше.

Я предполагаю, что RapidMiner выполняет какую-то проверку после завершения процессора, который использует код, который выдает ошибку, описанную выше, поэтому происходит сбой и процессор завершается.

Существует ли специальный правильный способ обработки и возврата DataFrames в RapidMiner для обхода ошибки, или есть что-то еще, что я мог бы проверить, чтобы выяснить, где находится проблема?

1 Ответ

1 голос
/ 26 января 2020

Для дальнейшей отладки проблемы я начал добавлять по очереди новые столбцы в свой результирующий DataFrame. Это привело меня к следующему открытию:

Проблема возникает, когда DataFrame содержит столбец (pandas .DataFrame.Series), элементами которого являются numpy .ndarrays или списки, элементами которых являются все нули (целые числа или числа с плавающей запятой). Когда процессор «Execute Python» возвращается, RapidMiner пытается определить, имеет ли каждая ячейка DataFrame значение Null или значение. Чтобы сделать это, основываясь на трассировке стека исключений, код должен проверять, имеет ли содержимое ячейки None, что недопустимо для этой проверки, когда элементы являются списками или numpy ndarrays. Следовательно, сообщение об исключении, которое сообщает нам, что истинное значение (или оно равно None или нет) не может быть определено, когда в массиве существует более одного элемента, несмотря на то, что все они равны нулю.

Итак, решение, в этом случае, чтобы гарантировать, что, когда возвращающий DataFrame имеет столбец, который содержит списки или массивы, ни один экземпляр их не содержит все нули. Можно также избежать помещения списков или массивов в возвращаемый DataFrame. Еще одна вещь, которая может сработать, - это сделать правильную проверку недействительности в коде (используя array.all ()), и когда найден массив или список со всеми нулевыми элементами, содержимое всей ячейки заменяется на None или другое значение, которое Получатель результата будет интерпретирован как ноль. Конечно, можно также дождаться следующей версии RapidMiner Studio, которая могла бы выполнить проверку надлежащим образом.

...