Numpy, где несколько условий, не может сравнить dtyped массив [object] со скаляром типа [bool]

#python #numpy

#python #numpy

Вопрос:

Я пытаюсь выполнить несколько условий в numpy where, но получаю ошибку: cannot compare a dtyped [object] array with a scalar of type [bool]

Вот строка:

 d7['CAD'] = np.where(d7['Category'] == 'Stack' amp; d7['Currency'] == fxratetable['from_currency'],d7['CAD'] * fxratetable['fx_rate'], d7['CAD'])
 

Все dtypes есть object , кроме fx_rate, который есть float64 .

Также другая мысль заключается в том, что я ищу одно значение с Category = Stack помощью, но ищу несколько значений с помощью my Currency = from_currency .

Кто-нибудь может помочь с этим?

Спасибо.

новая ошибка

 ValueError: Can only compare identically-labeled Series objects now. 
 

Это мое новое утверждение

 d7['CAD'] = np.where((d7['Category'] == 'Stack') amp; 
                     (d7['Currency'] == fxratetable['from_currency']),
                     d7['CAD'] * fxratetable['fx_rate'], 
                     d7['CAD'])
 

d7:

  -------------- ---------- ---------- 
| CAD          | Currency | Category |
 -------------- ---------- ---------- 
| -4350242.355 | GBP      | Stack    |
 -------------- ---------- ---------- 
| 424223.7584  | AUD      | Stack    |
 -------------- ---------- ---------- 
 

fxratetable:

  --------------- --------- 
| from_currency | fx_rate |
 --------------- --------- 
| GBP           | 1.367   |
 --------------- --------- 
| AUD           | 0.7706  |
 --------------- --------- 
 

Ожидается новый столбец CAD.

  ---------------- 
| CAD (expected) |
 ---------------- 
| -5948957.275   |
 ---------------- 
| 326991.5663    |
 ---------------- 
 

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

1. Оберните все сравнения, например == , в () , чтобы они были предварительно сформированы перед любой из amp; комбинаций.

2. привет, я ValueError: Can only compare identically-labeled Series objects уже понял. Это мое новое утверждение d7['CAD'] = np.where((d7['Category'] == 'Stack') amp; (d7['Currency'] == fxratetable['from_currency']),d7['CAD'] * fxratetable['fx_rate'], d7['CAD'])

3. Протестировали ли каждый вход в np.where ? Помните, что python оценивает все аргументы функции перед их передачей. Я подозреваю d7['Currency'] == fxratetable['from_currency'] , что это проблема, но у меня нет ваших фреймов данных для тестирования. При отладке разбивайте длинные выражения на части, чтобы лучше определить, в чем именно заключается проблема.

4. Я ввел некоторые примеры данных, вопрос, надеюсь, это поможет. К вашему сведению, есть больше «Категорий» и больше «валютных курсов», я просто решил показать два образца.

5. Это не помогает. Вы проверяли выражение, которое я выделил?

Ответ №1:

Лично я предпочитаю DataFrame.apply иметь дело с условиями.

 d7['CAD'] = d7.apply(lambda row: row.CAD * fxratetable[fxratetable.from_currency == row.Currency].fx_rate.item() 
                                 if row.Category == 'Stack' else row.CAD, axis=1)

 

fxratetable[fxratetable.from_currency == row.Currency] выбирает строку fxratetable , соответствующую правильной валюте, .fx_rate выбирает столбец курса и .item() вводит число вместо серии.

Вы можете видеть, что row.Category == 'Stack' остается только условие, проблемное сравнение рядов теперь является частью выбора.

И, наконец, axis=1 используется для применения функции к строкам фрейма данных (docu).

Я не тестировал это подробно, так что дайте мне знать, если это сработает.

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

1. Спасибо за этот ibd! однако вы только что использовали короткие формы для фреймов данных? т.е. вы использовали d вместо d7. Просто пытаюсь понять.

2. Извините за это, когда я попробовал это, я просто изменил d7 на d, а fxratetable на f, чтобы упростить задачу. Я отредактировал свой ответ 🙂

Ответ №2:

Проблема связана со второй частью логического выражения. Предположительно d7 , это больше, чем просто две строки, иначе этой проблемы не было бы. d7['Currency'] == fxratetable['from_currency'] сравнивает две серии подряд, и когда строки заканчиваются, fxratetable он больше не знает, с чем сравнивать d7 .

Я не знаю, настроены ли вы на использование NumPy или есть ограничения на то, что вы можете сделать, но оператор слияния справится с этим очень легко:

 # Merge the exchange rate
d7 = pd.merge(d7, fxratetable, left_on='Currency', right_on='from_currency', how='left')
# Find the rows which have a non-NaN exchange rate and multiply
d7['CAD'] = np.where(~np.isnan(d7['fx_rate']), d7['CAD']*d7['fx_rate'], d7['CAD'])
 

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

1. Привет, спасибо за это, но мне нужно только для Category = Stack, а не для других категорий в D7. Также ваше первое утверждение вносит таблицу fx в мою основную таблицу d7? Это просто добавляет к существующей таблице, я не хочу избавляться от каких-либо строк основной таблицы (d7) с помощью объединения.

Ответ №3:

Я думаю, это будет то, что вы ожидали. Я написал это понятным способом.

 d7 = pd.DataFrame({'CAD':[-4350242.355,424223.7584],'Currency':['GBP','AUD'],'Category':['Stack','Stack']})
fxratetable = pd.DataFrame({'from_currency':['GBP','AUD'],'fx_rate':[1.367,0.7706 ]})
_condition1 = d7['Category'] == 'Stack'
_condition2 = d7['Currency'] == fxratetable['from_currency']
d7['CAD (expected)'] = np.where(_condition1 amp; _condition2,d7['CAD'] * fxratetable['fx_rate'],d7['CAD'])
d7
 

ВЫВОД
введите описание изображения здесь