熊猫根据条件转置

时间:2021-03-18 13:28:36

标签: python pandas

我有一个数据框

Key   Col1 Col2 Col3   Colother
1     11    12    0     'a'
2     0     21    31    'b'
3     5     6     7     'c'

预期输出

Key   Col1 Col2 Col3   Colother  Colnew
1     11    12   0    'a'        11
1     11    12   0    'a'        12
2     0     21   31   'b'        21
2     0     21   31   'b'        31 
3     5     6    7    'c'        5
3     5     6    7    'c'        6
3     5     6    7    'c'        7

我曾尝试使用 df.T,但它的选项有限。因为我不想为 0 列创建行。现在我只剩下遍历行了。

4 个答案:

答案 0 :(得分:3)

尝试使用 agg 然后使用 explode

df['Colnew'] = df[['Col1','Col2','Col3']].agg(list,1)
df = df.explode('Colnew').loc[lambda x : x['Colnew']!=0]
df
Out[364]: 
   Key  Col1  Col2  Col3 Colother Colnew
0    1    11    12     0      'a'     11
0    1    11    12     0      'a'     12
1    2     0    21    31      'b'     21
1    2     0    21    31      'b'     31
2    3     5     6     7      'c'      5
2    3     5     6     7      'c'      6
2    3     5     6     7      'c'      7

答案 1 :(得分:3)

让我们试试 stackjoin

c = ['Col1', 'Col2', 'Col3']
df.join(df[c].mask(df[c].eq(0)).stack().droplevel(1).rename('ColNew'))

   Key  Col1  Col2  Col3 Colother  ColNew
0    1    11    12     0      'a'      11
0    1    11    12     0      'a'      12
1    2     0    21    31      'b'      21
1    2     0    21    31      'b'      31
2    3     5     6     7      'c'       5
2    3     5     6     7      'c'       6
2    3     5     6     7      'c'       7

答案 2 :(得分:2)

DataFrame.meltDataFrame.merge 一起使用:

df1 = df.melt(['Key','Colother'], value_name='Colnew').drop('variable', axis=1)
df = df.merge(df1[df1['value'].ne(0)])

print (df)
   Key  Col1  Col2  Col3 Colother Colnew
0    1    11    12     0      'a'     11
1    1    11    12     0      'a'     12
2    2     0    21    31      'b'     21
3    2     0    21    31      'b'     31
4    3     5     6     7      'c'      5
5    3     5     6     7      'c'      6
6    3     5     6     7      'c'      7

也可以在 query 中过滤,谢谢@Scott Boston 的建议:

df1 = df.melt(['Key','Colother'], value_name='Colnew').drop('variable', axis=1)
df = df.merge(df1.query('Colnew != 0'))
print (df)
   Key  Col1  Col2  Col3 Colother  Colnew
0    1    11    12     0      'a'      11
1    1    11    12     0      'a'      12
2    2     0    21    31      'b'      21
3    2     0    21    31      'b'      31
4    3     5     6     7      'c'       5
5    3     5     6     7      'c'       6
6    3     5     6     7      'c'       7

答案 3 :(得分:1)

您可以使用 join 来实现这一点

import pandas as pd
import numpy as np
x = [
    {
    "key": 1, "col1": 11, "col2": 12, "col3": 0, "colother": 'a'
    },
        {
    "key": 2, "col1": 0, "col2": 21, "col3": 31, "colother": 'b'
    },    {
    "key": 3, "col1": 5, "col2": 6, "col3": 7, "colother": 'c'
    },
]

df = pd.DataFrame(x)

print(df.join(df[["col1", "col2", "col3"]].stack().droplevel(1).rename('colnew').replace(0, np.nan).dropna()))     

输出:

   col1  col2  col3 colother  key  colnew
0    11    12     0        a    1    11.0
0    11    12     0        a    1    12.0
1     0    21    31        b    2    21.0
1     0    21    31        b    2    31.0
2     5     6     7        c    3     5.0
2     5     6     7        c    3     6.0
2     5     6     7        c    3     7.0