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

#python #pandas #dataframe #valueerror

#python #pandas #фрейм данных #ошибка значения

Вопрос:

Вот пример столбца моего набора данных, над которым я сейчас работаю:

 print (data)
     Credit Days
0             30
1   Cash amp; Carry
2   Cash amp; Carry
3             20
4             20
5             30
6             15
7             10
8             15
9   Cash amp; Carry
10            10
11            10
12            21
13  Cash amp; Carry
14            20
15            20
  

Таким образом, этот столбец содержит как строковые, так и целочисленные значения. Я должен преобразовать эти значения в целочисленные рейтинги и сохранить их во вновь созданном столбце, скажем, credit_days_rating. Для этого я написал код:

 data = pd.read_csv('test.csv', engine='python')

data['Credit Days'].astype(str)
if data['Credit Days']=='Cash amp; Carry':
    data['credit_days_rating'] = 4
else :
    data['Credit Days'].astype(int)
    if (data['Credit Days']>= 10) amp; (data['Credit Days']< 19):
        data['credit_days_rating'] = 3
    elif (data['Credit Days']>= 20) amp; (data['Credit Days']< 29):
        data['credit_days_rating'] = 2 
    else :
        data['credit_days_rating'] = 1 
  

Для этого я получаю следующий журнал ошибок:

 ---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-65-f6ecf070a2d4> in <module>()
      2 
      3 data['Credit Days'].astype(str)
----> 4 if (data['Credit Days']=='Cash amp; Carry'):
      5     data['credit_days_rating'] = 5
      6 else :

~/anaconda3/envs/tensorflow/lib/python3.5/site-packages/pandas/core/generic.py in __nonzero__(self)
   1119         raise ValueError("The truth value of a {0} is ambiguous. "
   1120                          "Use a.empty, a.bool(), a.item(), a.any() or a.all()."
-> 1121                          .format(self.__class__.__name__))
   1122 
   1123     __bool__ = __nonzero__

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

новый столбец должен выглядеть следующим образом:

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

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

1. if [1, 2 3] == 2 . Как бы вы ответили на это?

2. Какой ожидаемый вывод из данных? Что происходит снаружи (data['Credit Days']>= 10) amp; (data['Credit Days']< 19) ?

3. @jezrael Я обновил. Пожалуйста, проверьте.

4. Каковы другие условия для оценки?

5. @roganjosh : Я обновил код, чтобы перечислить все условия. пожалуйста, проверьте.

Ответ №1:

Вы можете использовать numpy.select для задания значений по списку условий, для сравнения числовых значений используйте to_numeric with errors='coerce' для преобразования нечисловых значений в NaN s:

 m1 = data['Credit Days']=='Cash amp; Carry'

s = pd.to_numeric(data['Credit Days'], errors='coerce')
m2 = (s>= 10) amp; (s< 19)
m3 = (s>= 20) amp; (s< 29)
masks = [m1,m2,m3]
vals = [4,3,2]
data['credit_days_rating'] = np.select(masks, vals, default=1)
print (data)
     Credit Days  credit_days_rating
0             30                   1
1   Cash amp; Carry                   4
2   Cash amp; Carry                   4
3             20                   2
4             20                   2
5             30                   1
6             15                   3
7             10                   3
8             15                   3
9   Cash amp; Carry                   4
10            10                   3
11            10                   3
12            21                   2
13  Cash amp; Carry                   4
14            20                   2
15            20                   2
  

Ответ №2:

это один из способов сделать это. Использование принудительного ввода для установки строк в NaN

 s = pd.Series([21,'Cash amp; Carry',10,20])

df = pd.DataFrame(s,columns=['Credit Days'])
df["credit_days_rating"] = 'NaN'
df.loc[df['Credit Days'] == 'Cash amp; Carry', 'credit_days_rating'] = 5
df.loc[(pd.to_numeric(df['Credit Days'], errors='coerce') >= 10) amp; (pd.to_numeric(df['Credit Days'], errors='coerce') < 19),'credit_days_rating'] = 3
  

Ответ №3:

Я предполагаю, что на самом деле вы хотите применить функцию к вашему столбцу, чтобы получить некоторый столбец только целочисленного типа. Это можно сделать следующим образом:

 data = ["some str", 10, 20, "some str", 1, 2, 3]
df = pd.DataFrame(data)

def my_function(value):
    if value == "some str":
        return 5
    elif value >= 10 or value < 19:
        return 3

df['new_col'] = df[0].apply(my_function)

df
  

Вывод тогда:

     0          new_col
0   some str    5
1   10          3
2   20          3
3   some str    5
4   1           3
5   2           3
6   3           3
  

Что (data[‘Credit Days’]==’Cash amp; Carry’) делает, так это возвращает экземпляр серии pandas с логическими значениями, например:

 df[0] == "some str"

0     True
1    False
2    False
3     True
4    False
5    False
6    False
Name: 0, dtype: bool
  

Если вместо этого вам нужно одно логическое значение для использования в условном операторе, вы захотите использовать внутренний метод ряда all() или any():

 (df[0] == "some str").any()

True
  

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

1. Если вы собираетесь сделать это таким образом, используйте np.where