2013-04-22 5 views
0

У меня DataFrame, который выглядит примерно так:условно объединить столбцы в кадре панды данных

x1 x2 
0 4 1 
1 0 2 
2 5 1 
3 0 3 
4 4 2 

Теперь я хочу, чтобы создать еще один столбец, который принимает в среднем столбцов x1 и x2 или возвращает 0 если x1 является 0:

x1 x2 ave 
0 4 1 2.5 
1 0 2 0 
2 5 1 3 
3 0 3 0 
4 4 2 3 

Ни этот

data['ave'] = (data['x1'] + data['x2'])/2 if data['x1'] > 0 else 0 

ни это

data['ave'] = (data['x1'] != 0)*(data['x1'] + data['x2'])/2 

работы по очевидным причинам (серия не может быть использована в этих операциях).

Я знаю, что это легко осуществить с помощью цикла, но есть ли у него короткий питонический способ сделать это?

Собственные данные питон ниже:

data = pd.DataFrame({'x1': (4,0,5,0,4), 'x2': (1,2,1,3,2)}) 

ответ

2

Вы очень близки. Оба ваших подхода должны работать только с настройками или двумя. Способ № 1:

>>> df = pd.DataFrame({'x1': (4,0,5,0,4), 'x2': (1,2,1,3,2)}) 
>>> df["ave"] = (df["x1"] != 0) * (df["x1"] + df["x2"])/2. 
>>> df 
    x1 x2 ave 
0 4 1 2.5 
1 0 2 0.0 
2 5 1 3.0 
3 0 3 0.0 
4 4 2 3.0 

Если Вы отпустите . в 2. и ваши столбцы представляют собой целые числа, вы можете не получить ожидаемый результат из-за целое деление, но Series может быть использован без каких-либо проблем.

Способ № 2:

df["ave"] = df.apply(lambda r: (r["x1"] + r["x2"])/2. if r["x1"] > 0 else 0, axis=1) 

Передайте функцию apply и указать axis=1.

Способ № 3а, 3b:

df["ave"] = df.mean(axis=1) * (df["x1"] != 0) 

или

df["ave"] = df[["x1", "x2"]].mean(axis=1) 
df["ave"][df["x1"] == 0] = 0 

И так далее.

+0

Спасибо, приятель! Первое решение работает - я не знаю, почему это не сработало сначала в моем случае, может быть, какая-то глупая опечатка ... Второй и третий решения - хорошие альтернативы, которые я, безусловно, буду использовать в более сложных ситуациях :) – sashkello