#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. Честно говоря, я хотел знать, что не так с моим кодом, который выдает ошибку?