简体   繁体   中英

Pandas pivot table arrangement no aggregation with sympbol

I want to pivot a pandas dataframe without aggregation, and instead of presenting the pivot index column vertically I want to present it horizontally.

data = {'Period:': ['Value1', 'Value2', 'Value3', 'Value1', 'Value2', 'Value3'],
        '2011': [10, 21, 20, 10, 39, 15],
        '2012': [12, 45, 19, 10, 39, 15],
        '2013': [12, 45, 19, 10, 39, 16],
        'symbol': ['a','a','a','b','b','b']}
df = pd.DataFrame(data)
print (df)


Period:  2011  2012  2013 symbol
0  Value1    10    12    12      a
1  Value2    21    45    45      a
2  Value3    20    19    19      a
3  Value1    10    10    10      b
4  Value2    39    39    39      b
5  Value3    15    15    16      b

But i want to have:

   Period:  Value1  Value2  Value3 symbol
0    2011      10      21      20      a
1    2012      12      45      19      a
2    2013      12      45      19      a
3    2011      10      39      15      b
4    2012      10      39      15      b
5    2013      10      39      16      b

You need to melt and pivot :

(df.melt(['Period:', 'symbol'])
 .pivot(['variable', 'symbol'], 'Period:', 'value')
 .reset_index().rename_axis(index=None, columns=None)
 .rename(columns={'variable':'Period:'})
 )

Output:

   Period: symbol  Value1  Value2  Value3
0     2011      a      10      21      20
1     2011      b      10      39      15
2     2012      a      12      45      19
3     2012      b      10      39      15
4     2013      a      12      45      19
5     2013      b      10      39      16

The answer by @mozway does the heavy lifting required by the question.

Here is a slight variation that renames/reorders rows and columns to get a result more closely matching the one in the question:

x = df.melt(['Period:', 'symbol'])
x = x.pivot(['variable', 'symbol'], 'Period:', 'value')
x = x.reset_index().rename_axis(columns=None).rename(columns={'variable':'Period:'})
x = x[['Period:'] + list(df['Period:'].unique()) + ['symbol']].sort_values(
    ['symbol', 'Period:']).reset_index(drop=True)
print(x)

Input:

  Period:  2011  2012  2013 symbol
0  Value1    10    12    12      a
1  Value2    21    45    45      a
2  Value3    20    19    19      a
3  Value1    10    10    10      b
4  Value2    39    39    39      b
5  Value3    15    15    16      b

Output:

  Period:  Value1  Value2  Value3 symbol
0    2011      10      21      20      a
1    2012      12      45      19      a
2    2013      12      45      19      a
3    2011      10      39      15      b
4    2012      10      39      15      b
5    2013      10      39      16      b

You can use stack / unstack and set_index / reset_index :

out = (df.set_index(['Period:', 'symbol']).unstack('Period:')
         .stack(level=0).reset_index('symbol'))
print(out)

# Output
Period: symbol  Value1  Value2  Value3
2011         a      10      21      20
2012         a      12      45      19
2013         a      12      45      19
2011         b      10      39      15
2012         b      10      39      15
2013         b      10      39      16

You could just do the transpose like this:

import pandas as pd

data = {'Period:': ['Value1', 'Value2', 'Value3', 'Value1', 'Value2', 'Value3'],
        '2011': [10, 21, 20, 10, 39, 15],
        '2012': [12, 45, 19, 10, 39, 15],
        '2013': [12, 45, 19, 10, 39, 16],
        'symbol': ['a','a','a','b','b','b']}
df = pd.DataFrame(data)
print (df)


dft = df.transpose()
dft

result:

              0       1       2       3       4       5
Period:  Value1  Value2  Value3  Value1  Value2  Value3
2011         10      21      20      10      39      15
2012         12      45      19      10      39      15
2013         12      45      19      10      39      16
symbol        a       a       a       b       b       b

Note that the sympol column is transposed too.

You can use:

df.melt(['Period:', 'symbol']).groupby(['symbol','variable', 'Period:'])['value'].agg(lambda x: x).unstack('Period:').reset_index().rename_axis(index=None, columns=None).rename(columns={'variable':'Period'})

Output:

symbol  Period  Value1  Value2  Value3
0   a   2011    10  21  20
1   a   2012    12  45  19
2   a   2013    12  45  19
3   b   2011    10  39  15
4   b   2012    10  39  15
5   b   2013    10  39  16

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM