2

My dataframe currently looks like:

ID               FIELD        VALUE
12463634          TEST         22.2 
12463634      E_REASON          010
12463634      IN_SCOPE            Y
12463635          TEST         99.5 
12463635      E_REASON          020
12463635      IN_SCOPE            N

I'd like my dataframe to look like:

ID           TEST     E_REASON     IN_SCOPE
12463634     22.2          010            Y
12463635     99.5          020            N

I have tried running this code:

df.pivot_table(index = "ID", columns = "FIELD", values = "VALUE")

However, I am seeing this error:

DataError: No numeric types to aggregate

Please advise. Thanks!

kjmerf
  • 4,275
  • 3
  • 21
  • 29

2 Answers2

2

Use pivot or unstack:

df = df.pivot(index = "ID", columns = "FIELD", values = "VALUE")
print (df)
FIELD    E_REASON IN_SCOPE  TEST
ID                              
12463634      010        Y  22.2
12463635      020        N  99.5

df = df.set_index(['ID', 'FIELD'])['VALUE'].unstack()
print (df)
FIELD    E_REASON IN_SCOPE  TEST
ID                              
12463634      010        Y  22.2
12463635      020        N  99.5

If duplicates need pivot_table with some aggregate function - sum or ','join:

print (df)
         ID     FIELD VALUE
0  12463634      TEST  22.2
1  12463634  E_REASON   010
2  12463634  IN_SCOPE     Y<-same ID and FIELED
3  12463634  IN_SCOPE    Y1<-same ID and FIELED
4  12463635      TEST  99.5
5  12463635  E_REASON   020
6  12463635  IN_SCOPE     N


df = df.pivot_table(index = "ID", columns = "FIELD", values = "VALUE", aggfunc='sum')
print (df)
FIELD    E_REASON IN_SCOPE  TEST
ID                              
12463634      010      YY1  22.2
12463635      020        N  99.5

Or:

df = df.pivot_table(index = "ID", columns = "FIELD", values = "VALUE", aggfunc=','.join)
print (df)
FIELD    E_REASON IN_SCOPE  TEST
ID                              
12463634      010     Y,Y1  22.2
12463635      020        N  99.5
jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252
0

An alternative option is to do something like:

df.groupby(['ID', 'FIELD']).sum().unstack()

This way you don't lose the label 'VALUES'

Explanation

You can groupby and sum() which will give you

In [31]: df.groupby(['ID', 'FIELD']).sum()
Out[31]:
                  VALUE
ID       FIELD
12463634 E_REASON   010
         IN_SCOPE     Y
         TEST      22.2
12463635 E_REASON   020
         IN_SCOPE     N
         TEST      99.5

Then the unstack moves the last indexed row to a column

Alexander McFarlane
  • 10,643
  • 9
  • 59
  • 100