TL;DR
A solution with pandas, I used the data of your example but added the brands to demonstrate the filtering, eliminating the lines with the brand "bar":
import io
import pandas as pd
from itertools import combinations
# Simulando o csv
csv = '''
nome,cor,marca,valor
Lapis, Verde, bic,"11,1"
Caneta, Vermelho, cristal,"12,25"
Lapiseira, Azul, foo,"15,45"
Lapis, Verde, foo,"12,00"
borracha, Branca, bar,"10,00"
borracha, Verde, bar,"11,00"
'''
# Lendo o csv
df = pd.read_csv(io.StringIO(csv))
# Filtrando o df para que nao contenha a marca 'bar'
df = df[~df.marca.str.contains('bar')]
# Criando coluna para uma tupla de descricao e valor (adapte ao seu contexto)
df['descricao'] = df.nome + df.cor + df.marca
df['item'] = list(zip(df.descricao, df.valor))
# Apresentando o dataframe resultante
print(df)
Exit:
nome cor marca valor descricao \
0 Lapis Verde bic 11.1 Lapis Verde bic
1 Caneta Vermelho cristal 12.25 Caneta Vermelho cristal
2 Lapiseira Azul foo 15.45 Lapiseira Azul foo
3 Lapis Verde foo 12.00 Lapis Verde foo
item
0 (Lapis Verde bic, 11.1)
1 (Caneta Vermelho cristal, 12.25)
2 (Lapiseira Azul foo, 15.45)
3 (Lapis Verde foo, 12.00)
The next step is to combine the items into a list:
# Fazendo as combinacoes
combs = list(combinations(df.item, 2))
# Apresentando as combinacoes
print(combs)
Exit:
[(('Lapis Verde bic', '11.1'), ('Caneta Vermelho cristal', '12.25')),
(('Lapis Verde bic', '11.1'), ('Lapiseira Azul foo', '15.45')),
(('Lapis Verde bic', '11.1'), ('Lapis Verde foo', '12.00')),
(('Caneta Vermelho cristal', '12.25'), ('Lapiseira Azul foo', '15.45')),
(('Caneta Vermelho cristal', '12.25'), ('Lapis Verde foo', '12.00')),
(('Lapiseira Azul foo', '15.45'), ('Lapis Verde foo', '12.00'))]
Finally we go through the list of combinations, selecting the ones that meet the condition, in the sum of the values <= 25
# Selecionando as combinacoes validas
valid_combs = []
max_value = 25
for comb in combs:
if float(comb[0][1]) + float(comb[1][1]) <= max_value:
valid_combs.append(comb)
# Apresentando o resultado
print(valid_combs)
Output (Tuples with combinations <= 25):
[(('Lapis Verde bic', '11.1'), ('Caneta Vermelho cristal', '12.25')),
(('Lapis Verde bic', '11.1'), ('Lapis Verde foo', '12.00')),
(('Caneta Vermelho cristal', '12.25'), ('Lapis Verde foo', '12.00'))]
Putting the final result into one pandas.DataFrame
:
final_list = []
for valid in valid_combs:
final_list.append((valid[0][0],valid[0][1], valid[1][0],valid[1][1],
float(valid[0][1])+float(valid[1][1])))
df_final = pd.DataFrame(final_list, columns=['Item 1', 'Valor',
'Item 2', 'Valor', 'Total'])
# Apresentando o resultado final
print(df_final)
Exit:
Item 1 Valor Item 2 Valor Total
0 Lapis Verde bic 11.1 Caneta Vermelho cristal 12.25 23.35
1 Lapis Verde bic 11.1 Lapis Verde foo 12.00 23.10
2 Caneta Vermelho cristal 12.25 Lapis Verde foo 12.00 24.25
Filtering the DataFrame
final:
Let’s filter the final result by removing the lines in which the word "Pen"
# Filtrando o df, removendo as combinacoes q tenham "Caneta"
df_filtered = df_final[~df_final['Item 1'].str.contains('Caneta') &
~df_final['Item 2'].str.contains('Caneta')]
# Apresentando o dataframe filtrado
print('','DataFrame filtrado: ', df_filtered,sep='\n')
Exit
DataFrame filtrado:
Item 1 Valor Item 2 Valor Total
1 Lapis Verde bic 11.1 Lapis Verde foo 12.00 23.1
See working on repl.it.
Aderson, thank you for your reply. It worked cool. I just got a question, is it possible to improve the outgoing message? And about the 'EXTRA' that I had commented... in case I wanted it to iterate only the items that had red color (for example), you could guide me on how to do?
– Marcelo João
@Marcelojoão Yes, having the information you can generate the output you want. About EXTRA, it is possible to filter as soon as you read the file in
read_csv
; there just do the validation you want and only do theyield
items that pass validation.– Woss
Got it. Just to clarify... the output in the case, it comes out of this format: ['Pencil', 'Pen']; ?
– Marcelo João
Yes, you can do whatever you want. Who defines the output is the
print
infor combination in result
; just change it according to your needs;– Woss
I get it, thank you.
– Marcelo João
Anderson, I came up with just one more question... the output is with repetition, for example: Pencil + Pen and Pen + Pencil. Is this easy to filter? So there’ll be no repetitions...
– Marcelo João
@Marcelojoão You must have done something different. The form of the answer does not generate this duplicate combination; the combinations it generates is (Pencil, Pen), (Pencil, Pencil) and (Pencil, Pen).
– Woss
True, I got confused. Thank you.
– Marcelo João