You can use groupby with aggregation size and unstack MultiIndex :
df = df.groupby(['actual','predicted']).size().unstack(fill_value=0) print (df) predicted Apple Banana Orange actual Apple 2 1 0 Banana 0 0 1 Orange 1 0 0
Another solution with crosstab :
df = pd.crosstab(df.actual, df.predicted) print (df) predicted Apple Banana Orange actual Apple 2 1 0 Banana 0 0 1 Orange 1 0 0
source share