2017-12-21 105 views
7

Với dataframe sau:gấu trúc nhân sử dụng các giá trị điển trên một số cột

import pandas as pd 
df = pd.DataFrame({ 
    'a': [1,2,3,4,5], 
    'b': [5,4,3,3,4], 
    'c': [3,2,4,3,10], 
    'd': [3, 2, 1, 1, 1] 
}) 

Và danh sách sau đây của thông số:

params = {'a': 2.5, 'b': 3.0, 'c': 1.3, 'd': 0.9} 

Sản xuất các đầu ra mong muốn sau:

a b c d output 
0 1 5 3 3 24.1 
1 2 4 2 2 21.4 
2 3 3 4 1 22.6 
3 4 3 3 1 23.8 
4 5 4 10 1 38.4 

Tôi đã sử dụng điều này để tạo kết quả:

df['output'] = [np.sum(params[col] * df.loc[idx, col] for col in df) 
       for idx in df.index] 

Tuy nhiên, đây là một cách tiếp cận rất chậm và tôi nghĩ rằng phải có cách tốt hơn bằng cách sử dụng chức năng gấu trúc tích hợp.

Tôi cũng nghĩ về điều này:

# Line up the parameters 
col_sort_key = list(df) 
params_sorted = sorted(params.items(), key=lambda k: col_sort_key.index(k[0])) 

# Repeat the parameters *n* number of times 
values = [v for k, v in params_sorted] 
values = np.array([values] * df.shape[0]) 

values 
array([[ 2.5, 3. , 1.3, 0.9], 
     [ 2.5, 3. , 1.3, 0.9], 
     [ 2.5, 3. , 1.3, 0.9], 
     [ 2.5, 3. , 1.3, 0.9], 
     [ 2.5, 3. , 1.3, 0.9]]) 

# Multiply and add 
product = df[col_sort_key].values * values 
product 
array([[ 2.5, 15. , 3.9, 2.7], 
     [ 5. , 12. , 2.6, 1.8], 
     [ 7.5, 9. , 5.2, 0.9], 
     [ 10. , 9. , 3.9, 0.9], 
     [ 12.5, 12. , 13. , 0.9]]) 

np.sum(product, axis=1) 
array([ 24.1, 21.4, 22.6, 23.8, 38.4]) 

Nhưng điều đó có vẻ hơi phức tạp! Bất kỳ suy nghĩ về một con gấu trúc bản địa cố gắng?

+0

Điểm đến Jezrael kể từ khi nó kết thúc nhanh nhất trong trường hợp sử dụng thực tế của tôi. Cách tiếp cận cũ của tôi chậm hơn 65 lần so với phương pháp mới này. Cảm ơn mọi người. – blacksite

+0

những gì về phép nhân vectơ ma trận trong numpy? Điều này sẽ kết thúc với một cái gì đó như: np.matmul (df.as_matrix(), np.array (2.5, 3.0, 1.3, 0.9)) –

Trả lời

3

Bạn có thể sử dụng assign + mul + sum:

df1 = df.assign(**params).mul(df).sum(1) 
print (df1) 
0 24.1 
1 21.4 
2 22.6 
3 23.8 
4 38.4 
dtype: float64 

dot + Series constructor:

df1 = df.dot(pd.Series(params)) 
print (df1) 
0 24.1 
1 21.4 
2 22.6 
3 23.8 
4 38.4 
dtype: float64 
5
(pd.Series(params)*df).sum(1) 
Out[816]: 
0 24.1 
1 21.4 
2 22.6 
3 23.8 
4 38.4 
dtype: float64 

Thông tin thêm:

pd.Series(params) 
Out[817]: 
a 2.5 
b 3.0 
c 1.3 
d 0.9 
dtype: float64 

(pd.Series(params)*df) 
Out[818]: 
     a  b  c d 
0 2.5 15.0 3.9 2.7 
1 5.0 12.0 2.6 1.8 
2 7.5 9.0 5.2 0.9 
3 10.0 9.0 3.9 0.9 
4 12.5 12.0 13.0 0.9 

Ví dụ của bạn, bạn có thể sử dụng dot cũng như

df.values.dot(np.array(list(params.values()))) 
Out[827]: array([ 24.1, 21.4, 22.6, 23.8, 38.4]) 
Các vấn đề liên quan