TylerNG
TylerNG

Reputation: 941

Pandas sumproduct

I have a df:

Value1  Value2  1   2   3
  1       A     0   1   2
  2       B     3   4   5
  3       C     2   2   2

I want to perform sumproduct between the rows and the columns 1 2 3:

Value1  Value2  1   2   3   sumproduct
  1       A     0   1   2   8    = 0*1 + 1*2 + 2*3
  2       B     3   4   5   26   = 3*1 + 4*2 + 5*3
  3       C     2   2   2   12   = 2*1 + 2*2 + 2*3

I've tried (df.values*df.columns.values).sum(1) but then I need to drop Value1 and Value2 columns first. Is there a better approach?

Many thanks!

Upvotes: 6

Views: 43511

Answers (4)

BENY
BENY

Reputation: 323226

What I will do

df.iloc[:,2:].dot([1,2,3])
Out[239]: 
0     8
1    26
2    12
dtype: int64

To make it automatic

s=df.iloc[:,2:]

s.dot(s.columns.astype(int))
Out[242]: 
0     8
1    26
2    12
dtype: int64

Upvotes: 9

David Leon
David Leon

Reputation: 1017

arr = [0]*len(df)
for i, v in enumerate([c for c in df.columns if not isinstance(c,str)]):
    arr = arr + df[v]*v

df['sumproduct'] = arr

or even:

cols = [c for c in df.columns if not isinstance(c, str)]
# or as @ilia
cols = pd.to_numeric(df.columns,errors='coerce').dropna()

df[cols].apply(lambda x: x*x.name).sum(axis='columns')

Upvotes: 1

biniow
biniow

Reputation: 401

df = pd.DataFrame({'1': [0, 3, 2], '2': [1, 4, 2], '3': [2, 5, 2]})    
df['sumproduct'] = df[1] * 1 + df[2] * 2 + df[3] * 3

UPDATE for generic case

valid_columns = [col for col in df.columns if col.isdigit()]
df['sumproduct'] = (df[valid_columns] * [int(x) for x in valid_columns]).sum(axis=1)

Upvotes: 5

ilia timofeev
ilia timofeev

Reputation: 1119

(df[['1','2','3']]*[1,2,3]).sum(axis=1)

Output:

0   8
1   26
2   12

Update: Universal approach

col = pd.to_numeric(df.columns,errors='coer')
(df[df.columns[~pd.isnull(col)]]*col.dropna()).sum(axis=1) 

Upvotes: 1

Related Questions