Назначение контейнеров в Пандах

Я хочу заменить None Записи в определенном столбце в Пандах с пустым списком.

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

Я пытался:

indices = np.equal(df[col],None)
df[col][indices] = []

а также

indices = np.equal(df[col],None)
df[col][indices] = list()

но оба решения терпят неудачу с:

ValueError: Length of replacements must equal series length

Зачем? Как я могу обновить эти конкретные строки с пустым списком?

2 ответа

Решение

Использование эндемичных списков не допускается при назначении и не рекомендуется делать это вообще.

Вы можете сделать это, если вы создаете с нуля

In [50]: DataFrame({ 'A' : [[],[],1]})
Out[50]: 
    A
0  []
1  []
2   1

[3 rows x 1 columns]

Причина, по которой это не разрешено, заключается в том, что без указаний (например, в numpy) вы можете сделать что-то вроде этого:

In [51]: df = DataFrame({ 'A' : [1,2,3] })

In [52]: df.loc[df['A'] == 2] = [ 5 ]

In [53]: df
Out[53]: 
   A
0  1
1  5
2  3

[3 rows x 1 columns]

Вы можете сделать присваивание, в котором длина значений True в маске равна длине списка / кортежа / ndarray в правой части (например, значение, которое вы устанавливаете). Панды допускают это, а также длину, которая точно равна lhs, и скаляр. Что-либо еще явно запрещено, потому что это неоднозначно (например, вы хотите выровнять это или нет?)

Например, представьте:

In [54]: df = DataFrame({ 'A' : [1,2,3] })

In [55]: df.loc[df['A']<3] = [5]
ValueError: cannot set using a list-like indexer with a different length than the value

Список 0-длины /tuple/ndarray считается ошибкой не потому, что это невозможно сделать, а, как правило, из-за ошибки пользователя, из-за которой неясно, что делать.

В итоге, не используйте списки внутри объекта панд. Это не эффективно, а просто делает интерпретацию трудной / невозможной.

Изменить: сохранил мой оригинальный ответ ниже, но я поднял его без тестирования, и это на самом деле не работает для меня.

import pandas as pd
import numpy as np
ser1 = pd.Series(['hi',None,np.nan])
ser2 = pd.Series([5,7,9])
df = pd.DataFrame([ser1,ser2]).T

Это джанки, я знаю. Кроме того, по-видимому, конструктор DataFrame (но не конструктор Series) приводит None к np.nan. Понятия не имею почему.

df.loc[1,0] = None

Итак, теперь у нас есть

    0     1
0   'hi'  5
1   None  7
2   NaN   9

df.columns = ['col1','col2']
mask = np.equal(df['col1'], None)
df.loc[mask, 'col1'] = []

Но это ничего не назначает. Фрейм данных выглядит так же, как и раньше. Я следую рекомендованному использованию из документации и назначаю базовые типы (строки и числа). Поэтому для меня проблема заключается в назначении объектов для записей в данных. Понятия не имею, что случилось.


(Оригинальный ответ)

Две вещи:

  1. Я не знаком с np.equal но pandas.isnull() также должен работать, если вы хотите захватить все нулевые значения.
  2. Вы делаете то, что называется "цепным назначением". Я не до конца понимаю проблему, но знаю, что она не работает. В документах.

Попробуй это:

mask = pandas.isnull(df[col])
df.loc[mask, col] = list()

Или, если вы хотите только поймать None и не np.nan:

mask = np.equal(df[col],None) 
df.loc[mask, col] = list()
Другие вопросы по тегам