Search code examples
pythonpandasdataframeapplyseries

Apply pandas function to column to create multiple new columns error


For this question i have found this example:

df = pd.DataFrame([[i] for i in range(5)], columns=['num'])
def powers(x):
    return x, x**2, x**3, x**4, x**5, x**6
df['p1'], df['p2'], df['p3'], df['p4'], df['p5'], df['p6'] = zip(*df['num'].apply(powers))
df

i changed the map() function to apply() function, it worked the same.

as you see we have passed a series for the apply() function: zip(*df['num'].apply(powers)).

This question's answer is good, But in my case of study i want to pass a dataFrame to the apply() function as: zip(*df[['num']].apply(powers)) by adding double*double brackets df[['num']] , but i got the following error: ValueError: not enough values to unpack (expected 6, got 3).

i didn't understand where the mistake is, can you help me please?


Solution

  • In my opinion zip with apply is not recommended combine, for add multiple new columns is possible use:

    df = pd.DataFrame([[i] for i in range(5)], columns=['num'])
    def powers(x):
        
        return pd.Series([x, x**2, x**3, x**4, x**5, x**6])
    df[['p1','p2','p3','p4','p5','p6']] = df['num'].apply(powers)
    
    print (df)
       num  p1  p2  p3   p4    p5    p6
    0    0   0   0   0    0     0     0
    1    1   1   1   1    1     1     1
    2    2   2   4   8   16    32    64
    3    3   3   9  27   81   243   729
    4    4   4  16  64  256  1024  4096
    

    For pass one column DataFrame is possible use:

    df = pd.DataFrame([[i] for i in range(5)], columns=['num'])
    def powers(x):
        
        return [x, x**2, x**3, x**4, x**5, x**6]
    df[['p1','p2','p3','p4','p5','p6']] = df[['num']].pipe(powers)
    
    print (df)
       num  p1  p2  p3   p4    p5    p6
    0    0   0   0   0    0     0     0
    1    1   1   1   1    1     1     1
    2    2   2   4   8   16    32    64
    3    3   3   9  27   81   243   729
    4    4   4  16  64  256  1024  4096
    

    For multiple columns:

    df = pd.DataFrame([[i] for i in range(5)], columns=['num'])
    df['new'] = df['num'] * 2
    def powers(x):
        
        return [x, x**2, x**3, x**4, x**5, x**6]
    
    
    df = pd.concat(df[['num','new']].pipe(powers), axis=1, keys=['p1','p2','p3','p4','p5','p6'])
    df.columns = df.columns.map(lambda x: f'{x[0]}_{x[1]}')
    print (df)
       p1_num  p1_new  p2_num  p2_new  p3_num  p3_new  p4_num  p4_new  p5_num  \
    0       0       0       0       0       0       0       0       0       0   
    1       1       2       1       4       1       8       1      16       1   
    2       2       4       4      16       8      64      16     256      32   
    3       3       6       9      36      27     216      81    1296     243   
    4       4       8      16      64      64     512     256    4096    1024   
    
       p5_new  p6_num  p6_new  
    0       0       0       0  
    1      32       1      64  
    2    1024      64    4096  
    3    7776     729   46656  
    4   32768    4096  262144