Заміна значень стовпців у пандах DataFrame


141

Я намагаюся замінити значення в одному стовпчику фрейму даних. У стовпці ("жіночий") містяться лише значення "жіночий" та "чоловічий".

Я спробував таке:

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

Але отримайте точно таку ж копію попередніх результатів.

Я б в ідеалі хотів отримати деякий вихід, який нагадує наступний елемент циклу.

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

Я переглянув документацію gotchas ( 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' або 'neutral', зробіть щось подібне:

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

Якщо стовпець містить більше рядків , ніж тільки 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

Я думаю, що у відповідь слід вказати, який тип об’єкта ви отримуєте у всіх запропонованих вище методах: це серія чи DataFrame.

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

При використанні .locабо ilocви отримаєте назад серії та серії НЕ .replaceметод, тому ви повинні використовувати такі методи , як apply, mapі так далі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.