Создайте столбец на основе значения другого столбца с помощью Pandas

#python #python-3.x #pandas

#python #python-3.x #pandas

Вопрос:

Пожалуйста, рассмотрите этот фрейм данных:

 date         value      
-------------------
20201001      -100
20200202      200
20200303       0
...
  

Я хочу иметь еще один очень простой столбец: «Статус»

если значение <0, то «Статус» = -1

если значение> 0, то «Статус» = 1

если значение = 0, то «Статус» = 0

Я написал этот код:

 data['Status'] = (data['Value'] / math.fabs(data['Value'])) if data['Value'] != 0 else 0
  

но я получил эту ошибку:

ValueError: значение истинности ряда неоднозначно. Используйте .empty , .bool(), .item(), .any() или.all() .

Как создать этот столбец без For цикла. Спасибо

Редактировать 1)Я написал код таким образом, но я получил ту же ошибку:

 data['Status'] = (data['Value'] / math.fabs(data['Value'])) if data[data['Value'] != 0] else 0
  

Ответ №1:

Используйте numpy.sign :

 data['Status'] = np.sign(data['Value'])
  

Если используются только целые числа Series.clip :

 data['Status'] = data['Value'].clip(lower=-1, upper=1)
  

Ваше решение, работающее с пониманием списка:

 data['Status'] = [x / math.fabs(x) if x != 0 else 0 for x in data['Value']]
print (data)
       date  value  Status
0  20201001   -100    -1.0
1  20200202    200     1.0
2  20200303      0     0.0
  

Производительность:

 #300k rows
data = pd.concat([data] * 100000, ignore_index=True)

In [72]: %timeit data['Status'] = np.sign(data['Value'])
3.2 ms ± 57.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [73]: %timeit data['Status'] = data['Value'].clip(lower=-1, upper=1)
5.99 ms ± 49.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [74]: %timeit data['Status'] = [x / math.fabs(x) if x != 0 else 0 for x in data['Value']]
144 ms ± 483 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)   
  

Комментарии:

1. Спасибо. Есть ли какой-нибудь способ без numpy ?

2. @Arian — Тогда возможно использование clip

3. спасибо, это работает. Но я хочу знать, что не так с моим кодом? Почему я не могу написать условие таким образом? Спасибо

4. @Arian — Если требуется производительность с несколькими if-else лучшими, лучше использовать numpy.select , но -1,0,1 здесь лучше всего np.sign

5. Честно говоря, я хотел знать, что не так с моим кодом, который выдает ошибку?