Как установить ячейку в NaN в кадре данных pandas

98

Я хотел бы заменить неверные значения в столбце фрейма данных на NaN.

mydata = {'x' : [10, 50, 18, 32, 47, 20], 'y' : ['12', '11', 'N/A', '13', '15', 'N/A']}
df = pd.DataFrame(mydata)

df[df.y == 'N/A']['y'] = np.nan

Однако последняя строка не работает и выдает предупреждение, потому что она работает с копией df. Итак, как правильно с этим справиться? Я видел много решений с iloc или ix, но здесь мне нужно использовать логическое условие.

Марк Морриссон
источник
Я чувствую, что название вводит в заблуждение. Проблема не в том, что вы хотите использовать NaN в вашем фрейме данных. Проблема в том, что вы «пытаетесь установить копию фрагмента из DataFrame».
Teepeemm,

Ответы:

124

просто используйте replace:

In [106]:
df.replace('N/A',np.NaN)

Out[106]:
    x    y
0  10   12
1  50   11
2  18  NaN
3  32   13
4  47   15
5  20  NaN

То, что вы пытаетесь, называется цепным индексированием: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

Вы можете использовать , locчтобы убедиться , что вы работать на оригинальном ДФ:

In [108]:
df.loc[df['y'] == 'N/A','y'] = np.nan
df

Out[108]:
    x    y
0  10   12
1  50   11
2  18  NaN
3  32   13
4  47   15
5  20  NaN
EdChum
источник
13

Хотя использование replaceвроде бы решает проблему, я хотел бы предложить альтернативу. Проблема с сочетанием числовых и некоторых строковых значений в столбце не для замены строк на np.nan, а для правильного отображения всего столбца. Могу поспорить, что исходный столбец, скорее всего, имеет объектный тип.

Name: y, dtype: object

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

Таким образом, хороший код преобразования будет

pd.to_numeric(df['y'], errors='coerce')

Укажите, errors='coerce'чтобы строки, которые не могут быть проанализированы до числового значения, становились NaN. Тип столбца будет

Name: y, dtype: float64
Северин Паппадукс
источник
10

Вы можете использовать замену:

df['y'] = df['y'].replace({'N/A': np.nan})

Также помните о inplaceпараметре для replace. Вы можете сделать что-то вроде:

df.replace({'N/A': np.nan}, inplace=True)

Это заменит все экземпляры в df без создания копии.

Точно так же, если вы столкнетесь с другими типами неизвестных значений, такими как пустая строка или значение None:

df['y'] = df['y'].replace({'': np.nan})

df['y'] = df['y'].replace({None: np.nan})

Ссылка: Pandas Latest - Заменить

Jmorrison
источник
2

Начиная с pandas 1.0.0, вам больше не нужно использовать numpy для создания нулевых значений в вашем фрейме данных. Вместо этого вы можете просто использовать pandas.NA (который имеет тип pandas._libs.missing.NAType), поэтому он будет обрабатываться как null внутри фрейма данных, но не будет иметь значение NULL вне контекста фрейма данных.

slevin886
источник
Хотя это не решает проблему OP, я проголосовал за, потому что он фактически ответил на вопрос в заголовке.
Teepeemm,
1
df.loc[df.y == 'N/A',['y']] = np.nan

Это решит вашу проблему. С двойным [] вы работаете с копией DataFrame. Вы должны указать точное местоположение в одном вызове, чтобы иметь возможность его изменить.

Джереми Бенишу
источник
0

Вы можете попробовать эти фрагменты.

В [16]: mydata = {'x': [10, 50, 18, 32, 47, 20], 'y': ['12', '11', 'N / A', '13', ' 15 ',' N / A ']}
В [17]: df = pd.DataFrame (mydata)

В [18]: df.y [df.y == "N / A"] = np.nan

Out [19]: df 
    ху
0 10 12
1 50 11
2 18 NaN
3 32 13
4 47 15
5 20 NaN
Rolandpeng
источник
0

df.replace ('значение столбца', np.NaN, inplace = True)

sameer_nubia
источник