Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pandas dataframe: how to group by values in a column and create new columns out of grouped values

I have a dataframe with two columns:

x y
0 1
1 1
2 2
0 5
1 6
2 8
0 1
1 8
2 4
0 1
1 7
2 3

What I want is:

x val1 val2 val3 val4
0 1 5 1 1
1 1 6 8 7
2 2 8 4 3

I know that the values in column x are repeated all N times.

like image 839
foebu Avatar asked Jan 01 '16 13:01

foebu


People also ask

How do I create a new column from the output of pandas Groupby () sum ()?

To create a new column for the output of groupby. sum(), we will first apply the groupby. sim() operation and then we will store this result in a new column.

How do I group values in a column in pandas?

Group by and value_counts Groupby is a very powerful pandas method. You can group by one column and count the values of another column per this column value using value_counts. Using groupby and value_counts we can count the number of activities each person did.

How do I split a column into multiple columns in pandas?

In Pandas, the apply() method can also be used to split one column values into multiple columns. The DataFrame. apply method() can execute a function on all values of single or multiple columns. Then inside that function, we can split the string value to multiple values.


1 Answers

You could use groupby/cumcount to assign column numbers and then call pivot:

import pandas as pd

df = pd.DataFrame({'x': [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2],
                   'y': [1, 1, 2, 5, 6, 8, 1, 8, 4, 1, 7, 3]})

df['columns'] = df.groupby('x')['y'].cumcount()
#     x  y  columns
# 0   0  1        0
# 1   1  1        0
# 2   2  2        0
# 3   0  5        1
# 4   1  6        1
# 5   2  8        1
# 6   0  1        2
# 7   1  8        2
# 8   2  4        2
# 9   0  1        3
# 10  1  7        3
# 11  2  3        3

result = df.pivot(index='x', columns='columns')
print(result)

yields

         y         
columns  0  1  2  3
x                  
0        1  5  1  1
1        1  6  8  7
2        2  8  4  3

Or, if you can really rely on the values in x being repeated in order N times,

N = 3
result = pd.DataFrame(df['y'].values.reshape(-1, N).T)

yields

   0  1  2  3
0  1  5  1  1
1  1  6  8  7
2  2  8  4  3

Using reshape is quicker than calling groupby/cumcount and pivot, but it is less robust since it relies on the values in y appearing in the right order.

like image 162
unutbu Avatar answered Sep 22 '22 23:09

unutbu