2016-11-08 4 views
1

Я хотел бы умножить (на месте) значения в одном столбце DataFrame на значения в другом столбце на основе условия в третьем столбце. Например:Условное умножение нескольких рядов с другим рядом

data = pd.DataFrame({'a': [1, 33, 56, 79, 2], 'b': [9, 12, 14, 5, 5], 'c': np.arange(5)}) 
data.loc[data.a > 10, ['a', 'b']] *= data.loc[data.a > 10, 'c'] 

Я хотел бы, чтобы это сделать, это умножить значения как «а» и «B» соответствующего значения (тот же строки) в «C» на основе состояния. Однако приведенный выше код просто приводит к значениям NaN в желаемом диапазоне.

Ближайший обходной путь я нашел в том, чтобы сделать это:

data.loc[data.a > 10, ['a', 'b']] = (data.loc[data.a > 10, ['a', 'b']].as_matrix().T * data.loc[data.a > 10, 'c']).T 

, который работает, но кажется, что это лучше (Pythonic) так, что я пропускаю.

ответ

4

вы можете использовать mul(..., axis=0) метод:

In [122]: mask = data.a > 10 

In [125]: data.loc[mask, ['a','b']] = data.loc[mask, ['a','b']].mul(data.loc[mask, 'c'], 0) 


In [126]: data 
Out[126]: 
    a b c 
0 1 9 0 
1 33 12 1 
2 112 28 2 
3 237 15 3 
4 2 5 4 
2

Вот одна альтернатива использовать Series.where() для обновления значений условно:

data[['a', 'b']] = data[['a', 'b']].apply(lambda m: m.where(data.a <= 10, m*data.c)) 

enter image description here

2

использование update

data.update(data.query('a > 10')[['a', 'b']].mul(data.query('a > 10').c, 0)) 

data 

enter image description here

1

Ну, кажется, NumPy может быть альтернативой здесь -

arr = data.values 
mask = arr[:,0] > 10 
arr[mask,:2] *= arr[mask,2,None] 

Мы просто извлекали values как массив, который является видом в dataframe и что позволяет нам работать на массиве и обновления будут автоматически отражаться в фрейме данных. Вот пример работы, чтобы показать прогресс -

In [507]: data # Input dataframe 
Out[507]: 
    a b c 
0 1 9 0 
1 33 12 1 
2 56 14 2 
3 79 5 3 
4 2 5 4 

Используйте предложенные коды -

In [508]: arr = data.values 

In [509]: mask = arr[:,0] > 10 

In [510]: arr[mask,:2] *= arr[mask,2,None] 

верифицировать результаты с dataframe -

In [511]: data 
Out[511]: 
    a b c 
0 1 9 0 
1 33 12 1 
2 112 28 2 
3 237 15 3 
4 2 5 4 

Давайте попробуем проверить через другой таким образом, что мы были на самом деле работающая там, где есть -

In [512]: np.may_share_memory(data,arr) 
Out[512]: True 
+0

Это не гарантирует, что это на самом деле вид; они случаются так, как у вас есть один тип dtype, но даже не может быть esp, если столбцы err созданы итеративно – Jeff

+0

@Jeff Спасибо! Помните об этом, полезная информация! – Divakar

0
# %% 
import pandas as pd 
import numpy as np 

data = pd.DataFrame({'a': [1, 33, 56, 79, 2], 
        'b': [9, 12, 14, 5, 5], 
        'c': np.arange(5)}) 

(data.loc[data.a>10, ['a','b']]\ 
.T * data.loc[data.a>10, 'c'])\ 
.T.append(data.loc[data.a<=10, ['a','b']])\ 
.T.append(data.c).T.sort() 
# %% 

Out[17]: 
    a b c 
0 1 9 0 
1 33 12 1 
2 112 28 2 
3 237 15 3 
4 2 5 4 
Смежные вопросы