Серия Pandas применяет лямбду: NoneType найден, но в серии есть только str и list - PullRequest
1 голос
/ 25 июня 2019

РЕДАКТИРОВАТЬ: Jezrael был правильный ответ на вопрос, который я задал ниже.К сожалению для меня, я задал не тот вопрос.Как оказалось, проблема заключалась в том, что списки строк в столбце DataFrame содержали None элементов, откуда и произошла ошибка.Пожалуйста, посмотрите ответ, который я добавил для кода, который я использовал, чтобы исправить это.

ВТОРОЕ РЕДАКТИРОВАНИЕ: «Джезраэль» обновил свой ответ на способ делать то, что я сделал, но более лаконично в лямбда-выражении.


У меня есть DataFrame, из которого я выбираю столбец, для которого я вызываю apply, которому я предоставляю параметр лямбда-выражения, который является оператором if.Я понимаю, что на этом этапе столбец рассматривается как серия.

Столбец состоит из строк и списков строк, последние из которых я хочу преобразовать в обычные строки путем объединения их элементов и замены этого списка полученной строкой, чтобы столбец FataFrame был простостроки.

Соответствующий код:

raw_data.address = raw_data.address.fillna('')

На этом этапе я перебрал весь адресный столбец и добавил все типы в набор - единственными элементами в этом наборе являются str и list.

raw_data.address.apply(lambda x: x if type(x) == str else ' '.join(x))

и

raw_data.address.apply(lambda x: x if isinstance(x, str) else ' '.join(x))

не работают.

Это сообщение об ошибке в обоих случаях:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-32-5e2dce775d20> in <module>
----> 1 raw_data.address.apply(lambda x: x if type(x) == str else ' '.join(x))

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pandas/core/series.py in apply(self, func, convert_dtype, args, **kwds)
   3589             else:
   3590                 values = self.astype(object).values
-> 3591                 mapped = lib.map_infer(values, f, convert=convert_dtype)
   3592 
   3593         if len(mapped) and isinstance(mapped[0], Series):

pandas/_libs/lib.pyx in pandas._libs.lib.map_infer()

<ipython-input-32-5e2dce775d20> in <lambda>(x)
----> 1 raw_data.address.apply(lambda x: x if type(x) == str else ' '.join(x))

TypeError: sequence item 0: expected str instance, NoneType found

Я не понимаю, почему это не работает.Насколько я понимаю, синтаксис правильный.

Ответы [ 2 ]

2 голосов
/ 25 июня 2019

Сравнить список и удалить None значения:

raw_data = pd.DataFrame({'address':[['a', 'b', None], 'c']})
print (raw_data)
        address
0  [a, b, None]
1             c

raw_data.address = (raw_data.address
                            .apply(lambda x: ' '.join(filter(None, x)) 
                                             if isinstance(x, list)
                                             else x))
print (raw_data)
  address
0     a b
1       c
0 голосов
/ 25 июня 2019

Как оказалось, проблема заключалась в том, что списки в DataFrame содержали None сами элементы.Чтобы решить эту проблему, вместо использования лямбда-функции в apply, я просто написал обычную функцию, которая использует встроенную функцию filter для удаления None s из списков:

def make_strings(thing):
    if isinstance(thing, list):
        return ' '.join(filter(None, thing))
    else:
        return str(thing)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...