Подтвердить что ты не робот

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:
          ...

Не уверен, куда идти отсюда. Любые идеи?

4b9b3361

Ответ 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