Home > Mobile >  Apply pandas function to column to create multiple new columns error
Apply pandas function to column to create multiple new columns error

Time:12-31

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?

CodePudding user response:

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  

CodePudding user response:

Alternative would be the following.

def powers(n):
    n=6
    cols=[x for x in np.arange(0,n 1)]
    for col in cols:
        df[f'num_{str(col)}'] = df['num'].apply(lambda x:x**col)
    return df
powers(df)

outcome1

    num  num_0  num_1  num_2  num_3  num_4  num_5  num_6
0    0      1      0      0      0      0      0      0
1    1      1      1      1      1      1      1      1
2    2      1      2      4      8     16     32     64
3    3      1      3      9     27     81    243    729
4    4      1      4     16     64    256   1024   4096

And if you needed p, this could do

def powers(n):
    n=6
    cols=[x for x in np.arange(1,n 1)]
    for col in cols:
        df[f'p{str(col)}'] = df['num'].apply(lambda x:x**col)
    return df
print(powers(df))

outcome 2

    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
  • Related