2

A dataframe stores some values in columns, passing those values to a function I get another dataframe. I'd like to concatenate the returned dataframe's columns to the original dataframe.

I tried to do something like

i = pd.concat([i, i[['cid', 'id']].apply(lambda x: xy(*x), axis=1)], axis=1) 

but it did not work with error:

ValueError: cannot copy sequence with size 2 to array axis with dimension 1

So I did like this:

def xy(x, y):
    return pd.DataFrame({'x': [x*2], 'y': [y*2]})

df1 = pd.DataFrame({'cid': [4, 4], 'id': [6, 10]})
print('df1:\n{}'.format(df1))


df2 = pd.DataFrame()
for _, row in df1.iterrows():
    nr = xy(row['cid'], row['id'])
    nr['cid'] = row['cid']
    nr['id'] = row['id']
    df2 = df2.append(nr, ignore_index=True)

print('df2:\n{}'.format(df2))

Output:

df1:
   cid  id
0    4   6
1    4  10

df2:
   x   y  cid  id
0  8  12    4   6
1  8  20    4  10

The code does not look nice and should work slowly.

Is there pandas/pythonic way to do it properly and fast working?

python 2.7

user3657041
  • 745
  • 8
  • 9

1 Answers1

1

Option 0
Most directly with pd.DataFrame.assign. Not very generalizable.

df1.assign(x=df1.cid * 2, y=df1.id * 2)

   cid  id  x   y
0    4   6  8  12
1    4  10  8  20

Option 1
Use pd.DataFrame.join to add new columns
This shows how to adjoin new columns after having used apply with a lambda

df1.join(df1.apply(lambda x: pd.Series(x.values * 2, ['x', 'y']), 1))

   cid  id  x   y
0    4   6  8  12
1    4  10  8  20

Option 2
Use pd.DataFrame.assign to add new columns This shows how to adjoin new columns after having used apply with a lambda

df1.assign(**df1.apply(lambda x: pd.Series(x.values * 2, ['x', 'y']), 1))

   cid  id  x   y
0    4   6  8  12
1    4  10  8  20

Option 3
However, if your function really is just multiplying by 2

df1.join(df1.mul(2).rename(columns=dict(cid='x', id='y')))

Or

df1.assign(**df1.mul(2).rename(columns=dict(cid='x', id='y')))
piRSquared
  • 285,575
  • 57
  • 475
  • 624