Замена значений столбцов в панде 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.