Использование if / else в Dataframe.assign () приводит к ValueError: истинное значение Series - PullRequest
1 голос
/ 29 марта 2019

У меня есть тонна преобразований данных, определенных на языке пакетного преобразования, который поддерживает эту структуру: x = iif (условие, a, b).Я хочу переписать их, используя dataframes.

Я использую Dataframe.assign (), но получаю ValueError: Истинное значение Series является неоднозначным.Используйте a.empty, a.bool (), a.item (), a.any () или a.all ().

    import pandas as pd
    df = pd.DataFrame(['apple', 'orange', 'granite'], columns=['name'])
    df.assign(taste = lambda x: 'rocky' if (x.name=='granite') else 'yummy')

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-39-e9ad71ccc45b> in <module>()
----> 1 df.assign(taste = lambda x: 'rocky' if (x.name=='granite') else 'yummy')

~\Anaconda3\lib\site-packages\pandas\core\frame.py in assign(self, **kwargs)
   3305         if PY36:
   3306             for k, v in kwargs.items():
-> 3307                 data[k] = com._apply_if_callable(v, data)
   3308         else:
   3309             # <= 3.5: do all calculations first...

~\Anaconda3\lib\site-packages\pandas\core\common.py in _apply_if_callable(maybe_callable, obj, **kwargs)
    403 
    404     if callable(maybe_callable):
--> 405         return maybe_callable(obj, **kwargs)
    406 
    407     return maybe_callable

<ipython-input-39-e9ad71ccc45b> in <lambda>(x)
----> 1 df.assign(taste = lambda x: 'rocky' if (x.name=='granite') else 'yummy')

~\Anaconda3\lib\site-packages\pandas\core\generic.py in __nonzero__(self)
   1571         raise ValueError("The truth value of a {0} is ambiguous. "
   1572                          "Use a.empty, a.bool(), a.item(), a.any() or a.all()."
-> 1573                          .format(self.__class__.__name__))
   1574 
   1575     __bool__ = __nonzero__

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

Сначала я подумал, что это связано с ограничениемключевые слова разрешены в assign (), но очень похожая конструкция работает с apply ():

df['name'].apply(lambda x: 'rocky' if (x=='granite') else 'yummy')

0    yummy
1    yummy
2    rocky
Name: name, dtype: object

Однако это не позволяет мне использовать условие if, которое использует несколько столбцов из фрейма данных.Есть ли способ заставить assign () работать?

Ответы [ 2 ]

2 голосов
/ 29 марта 2019

При вызове Series.apply лямбда получает каждое значение строки (то есть скалярное значение). При assign лямбда получает весь DataFrame. Понимание этого означает, что теперь вы можете делать что-то вроде

df.assign(taste=lambda x: np.where(x['name'] == 'granite', 'r', 'y'))

      name taste
0    apple     y
1   orange     y
2  granite     r

Или,

df.assign(taste=np.where(df['name'] == 'granite', 'r', 'y'))
      name taste
0    apple     y
1   orange     y
2  granite     r

Или, проще, для назначения на месте,

df['taste'] = np.where(df['name'] == 'granite', 'r', 'y')
df

      name taste
0    apple     y
1   orange     y
2  granite     r
2 голосов
/ 29 марта 2019

назначение - это не та функция, которую вы должны использовать при назначении условия

df['taste']=np.where(df['name'].eq('granite'),'rocky','yummy')
df
Out[513]: 
      name  taste
0    apple  yummy
1   orange  yummy
2  granite  rocky
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...