1

I have a list of item numbers as follows.

item_numbers = [1,2,5]

I also have a csv file that contains the ingredients of the item_numbers.

,sugar, protein, salt, oil
0, 0.2, 0.3, 0,   0
1, 0,    0,  0.2, 0.8
2, 0.4,  0,  0,   0

Now, I want to get the ingredients for the items in my list where the value is greater than zero (if value == 0, I don't need that ingredient)

E.g., item 1 in 'item_numbers' list -> [{'salt': 0.2}, {'oil': 0.8}]

My current code is as follows.

df = pd.read_csv(ingredients, sep = ',')
df = df.iloc[:,1:]
df = df.loc[item_numbers].dropna(how='all').gt(0).apply(lambda x: x.index[x].tolist(), 1)
ingredients = df.values.tolist()
print(ingredients)

Please help me.

1 Answers1

1

You can use:

df = df.loc[item_numbers].dropna(how='all').apply(lambda x: x[x > 0].to_dict(), 1)
ingredients = df.values.tolist()
print(ingredients)

[{'oil': 0.80000000000000004, 'salt': 0.20000000000000001}, {'sugar': 0.40000000000000002}]

For remove float precision numbers is possible use:

  1. Convert all values to str:
df = df.loc[item_numbers].dropna(how='all').apply(lambda x:x[x > 0].astype(str).to_dict(), 1)

ingredients = df.values.tolist()
print(ingredients)
[{'oil': '0.8', 'salt': '0.2'}, {'sugar': '0.4'}]
  1. Multiple by 10, 100 and then divide back:
df = df.loc[item_numbers].dropna(how='all').mul(10).apply(lambda x: x[x > 0].to_dict(), 1)

ingredients = df.values.tolist()
print(ingredients)
[{'oil': 8.0, 'salt': 2.0}, {'sugar': 4.0}]
jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252
  • Many thanks for the very useful answer. However, I worry y i get 0.80000000000000004 instead of 0.8 and so on. Do you know how to fix it? –  Sep 10 '17 at 14:31
  • 1
    Hmm, this is real `float`s - see [this](https://stackoverflow.com/a/39901954/2901002). Is it problem in output for next process? – jezrael Sep 10 '17 at 14:33
  • Thanks! Ya, I actually want the real value. However, my floats only have up to 3 decimal places (e.g., 0.333). Hence, will this be fixed if I round off my floats to 3 decimal points? –  Sep 10 '17 at 14:38
  • 1
    hmmm, I think round is not solution - check [this](https://stackoverflow.com/a/455634/2901002). But solution is cast all values to `string`. – jezrael Sep 10 '17 at 14:44
  • If I cast my values to string, then I get a problem in checking the value x>0. Anyway, thank you for your valuable comment :) –  Sep 10 '17 at 14:47
  • 1
    This is perfect! :) –  Sep 10 '17 at 14:54