Изменение первой строки DataFrame с учетом условия - PullRequest
0 голосов
/ 15 декабря 2018

У меня есть кадр данных, который выглядит следующим образом

import pandas as pd 
df = pd.DataFrame(data={"ID":[11,12,13,14,25],\
"Name":["Alice","Bob","Charlie", "Dan", "Erin"], "X":[1,0,0,0,0]})

   ID     Name  X
0  11    Alice  1
1  12      Bob  0
2  13  Charlie  0
3  14      Dan  0
4  25     Erin  0

Я хочу выбрать первую строку, для которой X равен 0, и изменить значение на 1. Я попытался

df[df["X"]==0]["X"].iloc[0] = 1

Но, похоже, это совсем не меняет фрейм данных df.Это странно для меня, так как я не получаю никакого сообщения об ошибке, и поскольку удаление =1 приводит к

>>> df[df["X"]==0]["X"].iloc[0]
 0

, как и ожидалось.

Я подозреваю, что при создании условия создается копияфрейм данных, и поэтому фрейм данных df просто никогда не изменяется.

Каков наилучший способ сделать это, чтобы получить

   ID     Name  X
0  11    Alice  1
1  12      Bob  1
2  13  Charlie  0
3  14      Dan  0
4  25     Erin  0

Конечно, это нужно делать систематически, так как япотребуется повторить процесс.

Большое спасибо заранее за вашу помощь.

Ответы [ 2 ]

0 голосов
/ 15 декабря 2018

Используйте at / iat для скалярной настройки

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

Вы можете использовать метки повсюду, аналогично @ решению Вена , но через at:

df.at[df['X'].eq(0).idxmax(), 'X'] = 1

Или вы можете целочисленное позиционное индексирование по всему через iat:

df.iat[df['X'].eq(0).values.argmax(), df.columns.get_loc('X')] = 1

Оба решения дают одинаковый результат.Первый, вероятно, более читабелен.

print(df)

   ID     Name  X
0  11    Alice  1
1  12      Bob  1
2  13  Charlie  0
3  14      Dan  0
4  25     Erin  0

pd.Series.idxmax / np.argmax векторизованы, но не особенно эффективны.Если важна эффективность, см. Эффективно вернуть индекс первого значения, удовлетворяющего условию в массиве .

0 голосов
/ 15 декабря 2018

Я буду использовать idxmax

df.loc[df.X.eq(0).idxmax(),'X']=1
df
Out[153]: 
   ID     Name  X
0  11    Alice  1
1  12      Bob  1
2  13  Charlie  0
3  14      Dan  0
4  25     Erin  0
...