2015-11-10 2 views
-2

У меня есть dataframe, и я написал следующую функцию для заполнения нового столбца:«Значение истинности Серии неоднозначно. Серия» против Element Fuction

df = pd.DataFrame(np.random.randn(10, 2), columns=['a', 'b']) 

def perc(a,b): 

    if a/b < 0: 
     n = 0 
    elif a/b > 1: 
     n = 1 
    else: 
     n = a/b 
    return n 

df['c']=perc(df['a'],df['b']) 

df[1:10] 

Он должен вычислить столбец процентов. Вот ошибка, которую я получаю:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). 

Я понимаю, что это связано с различием и неподходящими рядами вместо отдельных элементов. Но как я могу это исправить?

+0

Что поведение вы на самом деле хотите? Приведите пример ввода и ожидаемый результат, который демонстрирует всю логику, которую вы пытаетесь захватить. Вот моя догадка, если 'diff' были серией' [-1, 1, 3, 5] 'и' unc' были серией '[2, 2, 3, 3]', тогда 'dif/unc' будет' [-0.5, 0.5, 1, 1.6666] 'и вы хотите вернуть' [0, 0.5, 1, 1] ', это правильно? –

+0

Мне нужна колонка «C», чтобы показать уникальное значение для a/b этой строки. Но если его отрицательный он должен быть 0%, или если его более 100%, он должен показать 1. – Mateyobi

+0

Эй, да, вы поняли. Вы, должно быть, отредактировали его после моего ответа. Обратите внимание, что я отредактировал свой OP, чтобы быть более общим a/b. – Mateyobi

ответ

0

Что вы на самом деле просят немного трудно описать словами, но следующий пример захватывает его:

Если a является серия [-1, 1, 3, 5] и b является [2, 2, 3, 3], то a/b будет серия например [-0.5, 0.5, 1, 1.6666667], и то, что вы в конечном итоге хотите вернуть, - [0, 0.5, 1, 1].

Вы можете «задавать значения в 1» для серии, беря минимум этой серии с серией всех. Аналогично, вы можете гарантировать, что ничего ниже 0, взяв максимум серии с серией всех нулей. numpy позволяет вам сделать это легко:

def perc(a,b): 
    length = len(a) 
    return np.maximum(np.minimum(np.ones(length), a/b), np.zeros(length)) 
+0

Это поможет никому, кто найдет этот вопрос в Google. Данг, он должен был закрыть его. например http://stackoverflow.com/q/21415661/1240268 –

+0

Это работает! Но почему моя функция не работала? – Mateyobi

+0

@ AndyHayden, как бы вы применили ответ в своей ссылке на мой вопрос? Это мой первый вопрос, я бы не возражал, если бы вы распустили свой голос. – Mateyobi

0

Там является встроенный метод для этого clip:

In [134]: 
df = pd.DataFrame(np.random.randn(10, 2), columns=['a', 'b']) 
df 

Out[134]: 
      a   b 
0 0.676248 -0.320346 
1 -1.344982 2.170232 
2 -0.150036 -1.606179 
3 0.350467 0.386958 
4 0.551379 -0.378882 
5 -0.283632 -1.559516 
6 0.266356 -0.859321 
7 0.188118 1.275342 
8 0.109570 0.546783 
9 0.917231 -0.339878 

In [136]: 
df['c'] = (df['a']/df['b']).clip(lower=0, upper=1) 
df 

Out[136]: 
      a   b   c 
0 0.676248 -0.320346 0.000000 
1 -1.344982 2.170232 0.000000 
2 -0.150036 -1.606179 0.093412 
3 0.350467 0.386958 0.905699 
4 0.551379 -0.378882 0.000000 
5 -0.283632 -1.559516 0.181872 
6 0.266356 -0.859321 0.000000 
7 0.188118 1.275342 0.147504 
8 0.109570 0.546783 0.200390 
9 0.917231 -0.339878 0.000000 
+0

Это лучшее решение. Но есть ли способ обработать 1 элемент за раз? Что делать, если я хочу заполнить столбец c на основе более сложной формулы? Могу ли я сделать это так, как я пытался использовать data.frame? Я использую для доступа к функциям, которые обрабатывают одну строку за раз. – Mateyobi

+0

Вы можете это сделать, но для меня это все равно поражает использование pandas, которое предоставляет векторные методы, если вы собираетесь это сделать, тогда используйте 'apply' для обработки элемента – EdChum

Смежные вопросы