Использование Python Pandas для вычисления значения, при котором выполняются 2 условия из других столбцов

#python #python-3.x #pandas #dataframe

#python #python-3.x #pandas #фрейм данных

Вопрос:

У меня есть фрейм данных pandas, и я пытаюсь найти строки, в которых выполняются два условия, а затем вычислить значение.

Основная предпосылка заключается в:

  • Использование dataframe df,
    1. Замените значение в Adj_Int_Weight_Fuel на PreClear_Fuel_Adj, когда:
  • 1.1 PreClear_Fuel_Adj == 12; и
  • 1.2 Adj_Int_Weight_Fuel <= 1200
    1. Затем умножьте входящее значение на 100 (в настоящее время с плавающей точкой с 2 десятичными знаками, должно быть int)

Мне нужно, чтобы все остальные строки оставались неизменными и оставались в dataframe.

В настоящее время я пытаюсь использовать следующее:

 df['ADJ_INT_WEIGHT_FUEL'] = (df['PreClear_Fuel_Adj']*100).where(df['PreClear_Fuel_Adj'] == 12 amp; df['ADJ_INT_WEIGHT_FUEL'] <= 1200)
  

Пример
Оригинал

  --------------------- ------------------- 
| ADJ_INT_WEIGHT_FUEL | PreClear_Fuel_Adj |
 --------------------- ------------------- 
|                  10 |                 0 |
|                  30 |                12 | <-- Will be identified by .where()
|                  20 |                 0 |
|                   5 |                 0 |
|                  15 |                12 | <-- Will be identified by .where()
|                  25 |                 0 |
|                3500 |                12 |
 --------------------- ------------------- 
  

Вычислено

  --------------------- ------------------- 
| ADJ_INT_WEIGHT_FUEL | PreClear_Fuel_Adj |
 --------------------- ------------------- 
|                  10 |                 0 |
|                1200 |                12 | <-- Was identified by .where()
|                  20 |                 0 |
|                   5 |                 0 |
|                1200 |                12 | <-- Was identified by .where()
|                  25 |                 0 |
|                3500 |                12 |
 --------------------- ------------------- 
  

Проблемы
В настоящее время я получаю сообщение об ошибке. Pandas используется в ArcGIS Pro, поэтому в приведенном ниже дампе также будут некоторые сообщения об ошибках ArcGIS Pro. Однако, вообще говоря, мы можем рассматривать этот пример как общий фрейм данных pandas.

Кажется, что у меня либо проблема с типами данных, либо с использованием оператора amp;. Тем не менее, я не уверен, что мой синтаксис выбора и вычисления действительно правильный. Поэтому я мог бы использовать некоторую обратную связь, если там есть ошибка.

Спасибо!

 Traceback (most recent call last):
  File "C:Program FilesArcGISProbinPythonenvsarcgispro-py3Libsite-packagespandascoreopsarray_ops.py", line 274, in na_logical_op
    result = op(x, y)
  File "C:Program FilesArcGISProbinPythonenvsarcgispro-py3Libsite-packagespandascoreopsroperator.py", line 52, in rand_
    return operator.and_(right, left)
**TypeError: ufunc 'bitwise_and' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''**

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:Program FilesArcGISProbinPythonenvsarcgispro-py3Libsite-packagespandascoreopsarray_ops.py", line 288, in na_logical_op
    result = libops.scalar_binop(x, y, op)
  File "pandas_libsops.pyx", line 169, in pandas._libs.ops.scalar_binop
**ValueError: Buffer dtype mismatch, expected 'Python object' but got 'double'**

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<string>", line 479, in execute
  File "C:Program FilesArcGISProbinPythonenvsarcgispro-py3Libsite-packagespandascoreopscommon.py", line 64, in new_method
    return method(self, other)
  File "C:Program FilesArcGISProbinPythonenvsarcgispro-py3Libsite-packagespandascoreops__init__.py", line 552, in wrapper
    res_values = logical_op(lvalues, rvalues, op)
  File "C:Program FilesArcGISProbinPythonenvsarcgispro-py3Libsite-packagespandascoreopsarray_ops.py", line 366, in logical_op
    res_values = na_logical_op(lvalues, rvalues, op)
  File "C:Program FilesArcGISProbinPythonenvsarcgispro-py3Libsite-packagespandascoreopsarray_ops.py", line 298, in na_logical_op
    f"Cannot perform '{op.__name__}' with a dtyped [{x.dtype}] array "
TypeError: Cannot perform 'rand_' with a dtyped [float64] array and scalar of type [bool]
 Failed to execute (Tool).

  

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

1. Название вашего вопроса звучит так, будто панды занимаются математикой. 🙂

2. Исправлено: теперь для выполнения математики используйте Змею и несколько Медведей. Хороший подбор!

Ответ №1:

Попробуйте

 m = (df.PreClear_Fuel_Adj == 12) amp; (df.ADJ_INT_WEIGHT_FUEL <= 1200)
df['ADJ_INT_WEIGHT_FUEL'] *= m.astype(int)*100
  

Или

 df.loc[m, 'ADJ_INT_WEIGHT_FUEL'] = df['ADJ_INT_WEIGHT_FUEL']*100
  

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

1. Не будет ли этот ответ связан с необходимостью последующего объединения / слияния фреймов данных, потому что мы определяем новый df с помощью m =?

2. @anakainea это не фрейм данных, то есть серия, которую можно рассматривать как маску ~

3. Отметил это правильно, поскольку это позволяет избежать импорта numpy. На мой взгляд, отказ от импорта numpy снижает время загрузки и объем памяти, избегая дополнительной зависимости, так что это полезно.

Ответ №2:

Используйте np.where(condition, answer if condition, answer if not condition)

 import numpy as np
df['ADJ_INT_WEIGHT_FUEL']=np.where((df.PreClear_Fuel_Adj == 12)amp;(df.ADJ_INT_WEIGHT_FUEL <= 1200),
                          df.PreClear_Fuel_Adj*100,df.ADJ_INT_WEIGHT_FUEL)
print(df)
    



 ADJ_INT_WEIGHT_FUEL     PreClear_Fuel_Adj
0                   10                  0
1                 1200                 12
2                   20                  0
3                    5                  0
4                 1200                 12
5                   25                  0
6                 3500                 12