Замена значений столбцов в панде DataFrame


141

Я пытаюсь заменить значения в одном столбце данных. Столбец («женский») содержит только значения «женский» и «мужской».

Я пробовал следующее:

w['female']['female']='1'
w['female']['male']='0' 

Но получите точно такую ​​же копию предыдущих результатов.

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

if w['female'] =='female':
    w['female'] = '1';
else:
    w['female'] = '0';

Я просмотрел документацию по getchas ( http://pandas.pydata.org/pandas-docs/stable/gotchas.html ), но не могу понять, почему ничего не происходит.

Любая помощь будет оценена.

Ответы:


259

Если я правильно понимаю, вы хотите что-то вроде этого:

w['female'] = w['female'].map({'female': 1, 'male': 0})

(Здесь я преобразую значения в числа вместо строк, содержащих числа. Вы можете преобразовать их в "1"и "0", если вы действительно хотите, но я не уверен, зачем вам это нужно.)

Причина, по которой ваш код не работает, заключается в том, что использование ['female']столбца (второго 'female'в вашем w['female']['female']) не означает «выбрать строки, в которых значение равно« женский »». Это означает, что нужно выбрать строки с индексом «женский», которых может не быть в вашем DataFrame.


6
Спасибо. Именно то, что я искал. Если бы я должен был отобразить «женщина» на 1, а все остальное на «0». Как это будет работать?
— Черный,

17
используйте это только, если все значения в столбце даны в функции карты. Значения столбца, не указанные в функции карты, будут заменены на Nan.
— Чандра

1
Я бы также рекомендовал использовать .locсинтаксис, чтобы избежать SettingWithCopyWarning: pandas.pydata.org/pandas-docs/stable/…
— NickBraunagel

2
вместо .map я использовал .replace
— JS Noob

Как мне избавиться от «.» из тысяч на двух или более столбцах, не могу понять. Большое спасибо
— М. Марискал

115

Вы можете редактировать подмножество данных, используя loc:

df.loc[<row selection>, <column selection>]

В таком случае:

w.loc[w.female != 'female', 'female'] = 0
w.loc[w.female == 'female', 'female'] = 1

1
Как мне адаптировать его, чтобы мне не нужно было выбирать конкретные строки с помощью условия, только все строки в определенном столбце? Поэтому измените все ячейки в столбце на определенное значение.
— Дхрув Гулати

3
@DhruvGhulati, вы бы использовали df.loc [:, <выбор столбца>]




11

Вы также можете использовать applyс .getт. Е.

w['female'] = w['female'].apply({'male':0, 'female':1}.get):

w = pd.DataFrame({'female':['female','male','female']})
print(w)

Рамка данных w:

   female
0  female
1    male
2  female

Использование applyдля замены значений из словаря:

w['female'] = w['female'].apply({'male':0, 'female':1}.get)
print(w)

Результат:

   female
0       1
1       0
2       1 

Примечание: apply со словарем следует использовать, если все возможные значения столбцов в кадре данных определены в словаре, иначе оно будет пустым для тех, которые не определены в словаре.


8

Это очень компактно:

w['female'][w['female'] == 'female']=1
w['female'][w['female'] == 'male']=0

Еще один хороший:

w['female'] = w['female'].replace(regex='female', value=1)
w['female'] = w['female'].replace(regex='male', value=0)

Первый пример - цепная индексация, и о ней предупреждают, так как она не может гарантировать, является ли полученная df копией или представлением. Смотрите цепочечную индексацию
— Nordle

7

В качестве альтернативы есть встроенная функция pd.get_dummies для таких назначений:

w['female'] = pd.get_dummies(w['female'],drop_first = True)

Это дает вам фрейм данных с двумя столбцами, по одному для каждого значения, встречающегося в w ['female'], из которого вы отбрасываете первое (потому что вы можете вывести его из того, что осталось). Новый столбец автоматически будет назван в качестве строки, которую вы заменили.

Это особенно полезно, если у вас есть категориальные переменные с более чем двумя возможными значениями. Эта функция создает столько фиктивных переменных, сколько необходимо для различения всех случаев. Будьте осторожны, чтобы не назначить весь фрейм данных одному столбцу, а вместо этого, если w ['female'] может быть 'male', 'female' или 'нейтральным', сделайте что-то вроде этого:

w = pd.concat([w, pd.get_dummies(w['female'], drop_first = True)], axis = 1])
w.drop('female', axis = 1, inplace = True)

Затем у вас остаются две новые колонки, дающие вам фиктивную кодировку «женщина», и вы избавились от колонки со строками.


4

Использование Series.mapсSeries.fillna

Если ваш столбец содержит больше строк, чем only femaleи male, Series.mapв этом случае произойдет сбой, поскольку он вернется NaNдля других значений.

Вот почему мы должны связать это с fillna:

Пример почему .mapне получается :

df = pd.DataFrame({'female':['male', 'female', 'female', 'male', 'other', 'other']})

   female
0    male
1  female
2  female
3    male
4   other
5   other
df['female'].map({'female': '1', 'male': '0'})

0      0
1      1
2      1
3      0
4    NaN
5    NaN
Name: female, dtype: object

Для правильного метода, цепь mapс fillna, поэтому мы заполняем NaNзначения из исходного столбца:

df['female'].map({'female': '1', 'male': '0'}).fillna(df['female'])

0        0
1        1
2        1
3        0
4    other
5    other
Name: female, dtype: object

2

В pandasвызываемой также есть функция, factorizeкоторую вы можете использовать для автоматического выполнения этого типа работы. Он преобразует ярлыки с номерами: ['male', 'female', 'male'] -> [0, 1, 0]. Смотрите этот ответ для получения дополнительной информации.


0

Я думаю, что в ответе должно быть указано, какой тип объекта вы получаете во всех методах, предложенных выше: это Series или DataFrame.

Когда вы получите столбец с помощью w.female.или w[[2]](где, предположим, 2 - это номер вашего столбца), вы получите DataFrame. Так что в этом случае вы можете использовать методы DataFrame, как .replace.

Когда вы используете .locили ilocвозвращаете Series, а Series не имеют .replaceметода, поэтому вы должны использовать такие методы, как apply, mapи так далее.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.