Reputation: 197
I have two columns A and B. I want to subtract column B value with every value in column A and create a new column without using for-loop.
Below is my Dataframe
A B
0 5 3
1 3 2
2 8 1
Desired output
A B C D E
0 5 3 2 3 4
1 3 2 0 1 2
2 8 1 5 6 7
C = A - B[0]
D = A - B[1]
E = A - B[2]
Upvotes: 3
Views: 2768
Reputation: 9806
Using numpy's array broadcasting:
df = pd.DataFrame({'A':[5, 3, 8],
'B':[3, 2, 1]})
df2 = pd.DataFrame(df['A'].values[:, None] - df['B'].values, columns=['C', 'D', 'E'])
df = df.join(df2)
Result:
A B C D E
0 5 3 2 3 4
1 3 2 0 1 2
2 8 1 5 6 7
Explanation:
>>> df['A'].values[:, None]
array([[5],
[3],
[8]])
>>> df['B'].values
array([3, 2, 1])
When subtracting them, numpy "stretches" df['A'].values[:, None]
to:
array([[5, 5, 5],
[3, 3, 3],
[8, 8, 8]])
and df['B'].values
to:
array([[3, 2, 1],
[3, 2, 1],
[3, 2, 1]])
and the result of subtraction is:
array([[2, 3, 4],
[0, 1, 2],
[5, 6, 7]])
Upvotes: 4
Reputation: 11657
Here you go:
d = pd.DataFrame.from_dict({'A': {0: 5, 1: 3, 2: 8}, 'B': {0: 3, 1: 2, 2: 1}})
m = d.shape[0]
cols = [chr(67 + x) for x in range(m)]
d.join(pd.DataFrame(np.broadcast_to(d['A'], (m, m)).T - np.broadcast_to(d['B'], (m, m)), columns=cols))
Explanation: broadcast each series into a 3x3 matrix and subtracts them, make it into a dataframe and join it to original. The columns are auto-generated.
Upvotes: 0
Reputation: 28699
This might help:
1. replicate column A, according to the length of the dataframe
2. convert B to a numpy array
3. Subtract B from A, which should get u ur subtraction per row
4. concat back to main data
temp = pd.concat([df.A]*len(df), axis=1).sub(df.B.to_numpy())
final = pd.concat([df,temp], axis=1).set_axis(['A','B','C','D','E'],axis='columns')
final
A B C D E
0 5 3 2 3 4
1 3 2 0 1 2
2 8 1 5 6 7
Upvotes: 0