Подтвердить что ты не робот

Python pandas применяется функция, если значение столбца не равно NULL

У меня есть dataframe (в Python 2.7, pandas 0.15.0):

df=
       A    B               C
0    NaN   11             NaN
1    two  NaN  ['foo', 'bar']
2  three   33             NaN

Я хочу применить простую функцию для строк, которая не содержит значений NULL в определенном столбце. Моя функция максимально проста:

def my_func(row):
    print row

И мой применимый код выглядит следующим образом:

df[['A','B']].apply(lambda x: my_func(x) if(pd.notnull(x[0])) else x, axis = 1)

Он отлично работает. Если я хочу проверить столбцы "B" для значений NULL, pd.notnull() работает отлично. Но если я выберу столбец "C", который содержит объекты списка:

df[['A','C']].apply(lambda x: my_func(x) if(pd.notnull(x[1])) else x, axis = 1)

то я получаю следующее сообщение об ошибке: ValueError: ('The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()', u'occurred at index 1')

Кто-нибудь знает, почему pd.notnull() работает только для целых и строковых столбцов, но не для столбцов списка?

И есть ли лучший способ проверить значения NULL в столбце "C" вместо этого:

df[['A','C']].apply(lambda x: my_func(x) if(str(x[1]) != 'nan') else x, axis = 1)

Спасибо!

4b9b3361

Ответ 1

Проблема в том, что pd.notnull(['foo', 'bar']) работает элементно и возвращает array([ True, True], dtype=bool). Ваше условие if пытается преобразовать это в логическое, и это когда вы получите исключение.

Чтобы исправить это, вы можете просто обернуть оператор isnull с помощью np.all:

df[['A','C']].apply(lambda x: my_func(x) if(np.all(pd.notnull(x[1]))) else x, axis = 1)

Теперь вы увидите, что np.all(pd.notnull(['foo', 'bar'])) действительно True.

Ответ 2

Другой способ - просто использовать row.notnull().all() (без numpy), вот пример:

df.apply(lambda row: func1(row) if row.notnull().all() else func2(row), axis=1)

Вот полный пример вашего df:

>>> d = {'A': [None, 2, 3, 4], 'B': [11, None, 33, 4], 'C': [None, ['a','b'], None, 4]}
>>> df = pd.DataFrame(d)
>>> df
     A     B       C
0  NaN  11.0    None
1  2.0   NaN  [a, b]
2  3.0  33.0    None
3  4.0   4.0       4
>>> def func1(r):
...     return 'No'
...
>>> def func2(r):
...     return 'Yes'
...
>>> df.apply(lambda row: func1(row) if row.notnull().all() else func2(row), axis=1)
0    Yes
1    Yes
2    Yes
3     No

И более дружелюбный скриншот:-)

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

Ответ 3

У меня был список, содержащий столбцы, и NaN s. Итак, следующий работал у меня.

df.C.map(lambda x: my_func(x) if type(x) == list else x)

Ответ 4

all ['clean_name'] = all ['product_name']. apply (лямбда x: x.replace(',', '\,'), если x! = нет, x)