0

I have a dataframe df that looks like

Date Type
2010  A
1998  A
2003  B
2003  C
2007  D
2010  D
2015  B
2015  B
2006  C
2006  C
1998  D

I need to transform it and count the occurence of each Type for each year. So my expected output is:

    1998 2003 2006 2007 2010 2015
 A   1   0     0     0   1    0
 B   0   1     0     0   0    2 
 C   0   1     2     0   0    0
 D   1   0     0     1   1    0

As i understood, i need to usepivot here, right? Something like df.pivot(index='Type', columns='Data', values=???)

Polly
  • 1,057
  • 5
  • 14
  • 23
  • 3
    Actually I think what you want is [crosstab](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.crosstab.html), not pivot. – Ajean May 31 '16 at 15:33
  • look at http://stackoverflow.com/questions/36864929/creating-one-dataframe-from-another-using-pivot (create a new column filled with 1, then use pivot) – ysearka May 31 '16 at 15:39

2 Answers2

4

You can use pivot_table and pass len as the aggregate function:

df.pivot_table(index="Type", columns="Date",  aggfunc=len).fillna(0).astype(int)
Out[152]: 
Date  1998  2003  2006  2007  2010  2015
Type                                    
A        1     0     0     0     1     0
B        0     1     0     0     0     2
C        0     1     2     0     0     0
D        1     0     0     1     1     0

Like Ajean mentioned, you can use crosstab too:

pd.crosstab(df['Type'], df['Date'])
Out[153]: 
Date  1998  2003  2006  2007  2010  2015
Type                                    
A        1     0     0     0     1     0
B        0     1     0     0     0     2
C        0     1     2     0     0     0
D        1     0     0     1     1     0
Community
  • 1
  • 1
ayhan
  • 70,170
  • 20
  • 182
  • 203
2

If you don't want the empty values to show up, you can also use :

df.groupby(['Date', 'Type']).size().reset_index()

Which would give :

   Date Type  0
0  1998    A  1
1  1998    D  1
2  2003    B  1
3  2003    C  1
4  2006    C  2
5  2007    D  1
6  2010    A  1
7  2010    D  1
8  2015    B  2
3kt
  • 2,543
  • 1
  • 17
  • 29