0

I would like to transform values from a dataframe to columns of their own within the same dataframe, so that each name entry has only one row (instead of the same entry appearing in multiple rows for different column entries). Below is an example.

This is the dataframe I have:

    Name   Food  Grams
0  Tammy   Fish    200
1  Tammy   Rice    105
2  Wenny   Rice    250
3  Wenny   Eggs    100
4  Wenny   Eggs     90
5  Steve  Plums     10
6  Steve   Eggs     90

(code for dataframe is below)

And I would like to transform this to the following:

    Name Fish Rice Eggs Plums
0  Tammy  200  105  NaN   NaN
1  Wenny  NaN  250  190   NaN
2  Steve  NaN  NaN   90    10

(The NaNs can also be 0, both are fine).

Note that in situations where the same person eats the same food on different occasions, the grams of food consumed are added together within the same column (e.g. with Wenny and eggs).

Code for df:

data = {'Name': ['Tammy', 'Tammy', 'Wenny', 'Wenny', 'Wenny', 
        'Steve', 'Steve'],
        'Food': ['Fish', 'Rice', 'Rice', 'Eggs', 
        'Eggs', 'Plums', 'Eggs'],
        'Grams': [200, 105, 250, 100, 90, 10, 90]}

df = pd.DataFrame(data, columns = ['Name', 'Food', 'Grams'])
Tonechas
  • 13,398
  • 16
  • 46
  • 80
Dan
  • 11
  • 2
  • [pivot tables](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.pivot_table.html) – noah Jan 05 '21 at 17:37
  • I see that you need to sum the grams of food consumed. Try `df.groupby(['Name','Food']).sum().unstack()` – Toukenize Jan 05 '21 at 17:42

1 Answers1

1

Use -

df.pivot_table(index=['Name'], columns=['Food'], values=['Grams'], 
               fill_value=0, aggfunc='sum')

Output

      Grams                
Food   Eggs Fish Plums Rice
Name                       
Steve    90    0    10    0
Tammy     0  200     0  105
Wenny   190    0     0  250

Use fill_value parameter to replace NaN with 0s

As @Toukenize got to the groupby solution before I could post it as an alternative, credit where due -

df.groupby(['Name','Food']).sum().unstack()
Vivek Kalyanarangan
  • 8,951
  • 1
  • 23
  • 42