How to remove a list from another one ?

Hi all,

Could anyone help me to do this please : remove a list from another ?

Ex :
Col0 : [ a, b, a, d, c]
Col1 : [a , d]
=> Col2 = Col0 - Col1 = [ a, b, c]

Thanks in advanced for your help!

Best regards,

Thanh Thanh

Hi @tttpham

KNIME has -Set Operator- node () which allows to do this kind of operation:

This could be achieved using the complement operator.

Hope this helps.

Best

Ael

3 Likes

Hi aworker,

Thanks for your reply. I just try the node, however, that’s not exactly what I need, cause it remove all the “a” elements :frowning:

You know another way ?

Thanks much!

Best regards,

Thanh Thanh

Hi @tttpham , this was a challenge I looked into a couple of weeks ago.

I could not find a way in Knime nodes where it could remove only 1 instance of an element. Knime would remove all instances of the element as you found out.

I used a Python script to achieve this. The trick is to use list.remove() as it allows you to remove only 1 occurrence of it.

Check out this thread for more details and sample workflow:

2 Likes

Hi @tttpham , I put something together for you.

The workflow looks like this:
image

The operation is done in the Python script, so it’s really all that you need.

The 2 Collection to String nodes is just to be able to view the elements in each list. By default, Knime only shows a certain amount of elements of a list:
image

As you can see, it’s hard to know what the elements are.

Temporarily converting them, and we can see the input data now:
image

I created 2 tests sample, 1 that is yours, and the other one a case where I want to remove 2 instances of “a” out of 3 to show that we can do as many instances as we want.

The Python code is really simple and looks like this:

# Copy input to output
output_table_1 = input_table_1.copy()

count = len(input_table_1['Col1'])
output_table_1['Col2'] = output_table_1['Col0'].copy()

for i in range(count):
  for col1 in (input_table_1['Col1'][i]):
    output_table_1['Col2'][i].remove(col1)

Now, with the .copy() function, it is supposed to make a copy without referencing to the original. So, this means that if I am removing elements from the copy, it should not modify the original. For some reason, it is also modifying the original:
image

It is giving me the correct Col2, but it is also modifying Col0 for some reasons.

I’m not sure if it’s my Python environment that has an issue, or if it’s a Knime issue, or if I’m missing something (I’m not a Python developer).

You can try the workflow on your side to see if you get the same results, or if your Col0 stays as the original values.

Here’s the workflow: Remove one instance of element from list.knwf (16.2 KB)

Now, if you do get the same results as mine, I’m providing you the additional operation to rectify this via a Joiner node:
image

This will guarantee the proper results:
image

Here’s the workflow with the addition: Remove one instance of element from list.knwf (20.9 KB)

3 Likes

Hello @tttpham and @bruno29a,

here is solution with Column Expressions. (And KNIME nodes solution of which I’m not proud of :sweat_smile:)
2021_11_04_MinusListOperator.knwf (47.4 KB)

Br,
Ivan

5 Likes

Nice one @ipazin !

You Knime nodes solution does not work as expected though when there are more than 1 row…

The Column Expression one works well. Great logic implemented there :slight_smile:

1 Like

Tnx @bruno29a :slight_smile:

Well that’s where I’m not proud of it cause you have to involve a loop :sweat_smile:

Ivan

1 Like

Thanks @ipazin and @bruno29a, really appreciate your help !!

I’ll go with the column expression solution ( but instead of removeChars(arrayToString(arraySubset(column("AggregatedValues2"),i ,i+1 )),"{}" )

I put column("AggregatedValues2")[i] to simplify a little bit )

Again, thank you so much !

Have a nice day !

Thanh Thanh

3 Likes

Nice simplification! Didn’t know this will work. Great!
Ivan

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.