1

I have a dataset in pandas with column pid (patient id), and code (drug code), sorted in rows as the example shows. I need to convert them to 1 patient/row, and list all the drugs as attributes for each patient.

What I have now:

pid  code
1    Az
1    Bn
2    Az
2    Bn
2    C4
3    Bn
3    C4
3    Dx
4    Az
4    Bn
4    Dx
4    E
5    C4
5    Dx
5    E

I need to convert it to:

pid  Az   Bn   C4   Dx   E
1    y    y    n    n    n
2    y    y    y    n    n
3    n    y    y    y    n
4    y    y    n    y    y
5    n    n    y    y    y
AnonX
  • 251
  • 3
  • 15

3 Answers3

4

IIUC crosstab

pd.crosstab(df.pid,df.code).replace({1:'y',0:'n'})
Out[231]: 
code Az Bn C4 Dx  E
pid                
1     y  y  n  n  n
2     y  y  y  n  n
3     n  y  y  y  n
4     y  y  n  y  y
5     n  n  y  y  y
BENY
  • 317,841
  • 20
  • 164
  • 234
2

One way is to pivot your dataframe

new_df = df.assign(values='y').pivot(index='pid', columns='code', values='values').replace({None:'n'})

>>> new_df
code Az Bn C4 Dx  E
pid                
1     y  y  n  n  n
2     y  y  y  n  n
3     n  y  y  y  n
4     y  y  n  y  y
5     n  n  y  y  y
sacuL
  • 49,704
  • 8
  • 81
  • 106
2

Having fun!

Fun 1

Create a Series with a MultiIndex and unstack

pd.Series('y', df.values.T.tolist()).unstack(fill_value='n')

  Az Bn C4 Dx  E
1  y  y  n  n  n
2  y  y  y  n  n
3  n  y  y  y  n
4  y  y  n  y  y
5  n  n  y  y  y

Fun 2

Use defaultdict

d = defaultdict(dict)

for i, p, c in df.itertuples():
    d[c][p] = 'y'

pd.DataFrame(d).fillna('n')

  Az Bn C4 Dx  E
1  y  y  n  n  n
2  y  y  y  n  n
3  n  y  y  y  n
4  y  y  n  y  y
5  n  n  y  y  y

Fun 3

i, r = pd.factorize(df.pid)
j, c = pd.factorize(df.code)
e = np.empty((len(r), len(c)), str)
e.fill('n')
e[i, j] = 'y'
pd.DataFrame(e, r, c)

  Az Bn C4 Dx  E
1  y  y  n  n  n
2  y  y  y  n  n
3  n  y  y  y  n
4  y  y  n  y  y
5  n  n  y  y  y
piRSquared
  • 285,575
  • 57
  • 475
  • 624