Python PANDAS, измените одно значение на другое значение
Я пытаюсь перепрограммировать мой код Stata на Python для повышения скорости, и я был направлен в сторону PANDAS. Тем не менее, мне трудно переносить голову о том, как обрабатывать данные.
Скажем, я хочу перебрать все значения в столбце head ID. Если этот идентификатор соответствует определенному номеру, то я хочу изменить два соответствующих значения FirstName и LastName.
В Stata это выглядит так:
replace FirstName = "Matt" if ID==103
replace LastName = "Jones" if ID==103
Таким образом, это заменяет все значения в FirstName, которые соответствуют значениям ID == 103 для Matt.
В PANDAS, я пытаюсь что-то вроде этого
df = read_csv("test.csv")
for i in df['ID']:
if i ==103:
...
Не уверен, куда идти отсюда. Любые идеи?
Ответы
Ответ 1
Один из вариантов - использовать функции разрезания и индексирования Python для логической оценки мест, где выполняется ваше условие, и перезаписать там данные.
Предполагая, что вы можете загружать свои данные непосредственно в pandas
с помощью pandas.read_csv
, тогда вам может быть полезен следующий код.
import pandas
df = pandas.read_csv("test.csv")
df.loc[df.ID == 103, 'FirstName'] = "Matt"
df.loc[df.ID == 103, 'LastName'] = "Jones"
Как упоминалось в комментариях, вы также можете выполнить присвоение обоим столбцам за один снимок:
df.loc[df.ID == 103, ['FirstName', 'LastName']] = 'Matt', 'Jones'
Обратите внимание, что вам понадобится pandas
версия 0.11 или новее, чтобы использовать loc
для операций присваивания перезаписи.
Другой способ сделать это - использовать то, что называется цепным назначением. Поведение этого менее стабильно и поэтому не считается лучшим решением, но полезно знать о:
import pandas
df = pandas.read_csv("test.csv")
df['FirstName'][df.ID == 103] = "Matt"
df['LastName'][df.ID == 103] = "Jones"
Ответ 2
Вы можете использовать map
, он может отображать vales из dictonairy или даже пользовательской функции.
Предположим, что это ваш df:
ID First_Name Last_Name
0 103 a b
1 104 c d
Создайте dicts:
fnames = {103: "Matt", 104: "Mr"}
lnames = {103: "Jones", 104: "X"}
И карта:
df['First_Name'] = df['ID'].map(fnames)
df['Last_Name'] = df['ID'].map(lnames)
Результат будет:
ID First_Name Last_Name
0 103 Matt Jones
1 104 Mr X
Или используйте пользовательскую функцию:
names = {103: ("Matt", "Jones"), 104: ("Mr", "X")}
df['First_Name'] = df['ID'].map(lambda x: names[x][0])
Ответ 3
Этот вопрос по-прежнему можно было бы посещать достаточно часто, чтобы он предлагал добавление к ответу г-на Касси. Встроенный класс dict
может быть подклассифицирован так, что для "отсутствующих" ключей возвращается значение по умолчанию. Этот механизм хорошо работает для pandas. Но см. ниже.
Таким образом, можно избежать ошибок ключа.
>>> import pandas as pd
>>> data = { 'ID': [ 101, 201, 301, 401 ] }
>>> df = pd.DataFrame(data)
>>> class SurnameMap(dict):
... def __missing__(self, key):
... return ''
...
>>> surnamemap = SurnameMap()
>>> surnamemap[101] = 'Mohanty'
>>> surnamemap[301] = 'Drake'
>>> df['Surname'] = df['ID'].apply(lambda x: surnamemap[x])
>>> df
ID Surname
0 101 Mohanty
1 201
2 301 Drake
3 401
То же самое можно сделать проще следующим образом. Использование аргумента 'default' для метода get
объекта dict делает ненужным подкласс dict.
>>> import pandas as pd
>>> data = { 'ID': [ 101, 201, 301, 401 ] }
>>> df = pd.DataFrame(data)
>>> surnamemap = {}
>>> surnamemap[101] = 'Mohanty'
>>> surnamemap[301] = 'Drake'
>>> df['Surname'] = df['ID'].apply(lambda x: surnamemap.get(x, ''))
>>> df
ID Surname
0 101 Mohanty
1 201
2 301 Drake
3 401