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

Установить значение первого элемента в фрагменте в python pandas

Итак, я хотел бы сделать фрагмент кадра данных, а затем установить значение первого элемента в этом фрагменте без копирования фрейма данных. Например:

df = pandas.DataFrame(numpy.random.rand(3,1))
df[df[0]>0][0] = 0

Этот фрагмент не имеет значения и только для примера и снова вернет весь фрейм данных. Точка, делая это, как в примере, вы получаете настройку с предупреждением об ошибке (понятно). Я также попробовал срез сначала, а затем использовал ILOC/IX/LOC и дважды использовал ILOC, то есть что-то вроде:

df.iloc[df[0]>0,:][0] = 0
df[df[0]>0,:].iloc[0] = 0

И ни одна из этих работ не работает. Опять же - я не хочу делать копию фрейма данных, даже если он имеет идентификатор только нарезанной версии.

EDIT: Кажется, есть два способа, используя маску или IdxMax. Метод IdxMax работает, если ваш индекс уникален, а метод маски - нет. В моем случае индекс не уникален, о чем я забыл упомянуть в начальном посте.

4b9b3361

Ответ 1

Таким образом, используя некоторые ответы, мне удалось найти способ одного лайнера для этого:

np.random.seed(1)
df = pd.DataFrame(np.random.randint(4, size=(5,1)))
print df
   0
0  1
1  3
2  0
3  0
4  3
df.loc[(df[0] == 0).cumsum()==1,0] = 1
   0
0  1
1  3
2  1
3  0
4  3

По сути, это использование маски внутри с концом.

Ответ 2

Я думаю, вы можете использовать idxmax для получения индекса первого значения True, а затем установить loc:

np.random.seed(1)
df = pd.DataFrame(np.random.randint(4, size=(5,1)))
print (df)
   0
0  1
1  3
2  0
3  0
4  3

print ((df[0] == 0).idxmax())
2

df.loc[(df[0] == 0).idxmax(), 0] = 100
print (df)
     0
0    1
1    3
2  100
3    0
4    3

df.loc[(df[0] == 3).idxmax(), 0] = 200
print (df)
     0
0    1
1  200
2    0
3    0
4    3

EDIT:

Решение с уникальным индексом:

np.random.seed(1)
df = pd.DataFrame(np.random.randint(4, size=(5,1)), index=[1,2,2,3,4])
print (df)
   0
1  1
2  3
2  0
3  0
4  3

df = df.reset_index()
df.loc[(df[0] == 3).idxmax(), 0] = 200
df = df.set_index('index')
df.index.name = None
print (df)
     0
1    1
2  200
2    0
3    0
4    3

EDIT1:

Решение с MultiIndex:

np.random.seed(1)
df = pd.DataFrame(np.random.randint(4, size=(5,1)), index=[1,2,2,3,4])
print (df)
   0
1  1
2  3
2  0
3  0
4  3

df.index = [np.arange(len(df.index)), df.index]
print (df)
     0
0 1  1
1 2  3
2 2  0
3 3  0
4 4  3

df.loc[(df[0] == 3).idxmax(), 0] = 200
df = df.reset_index(level=0, drop=True)

print (df)
     0
1    1
2  200
2    0
3    0
4    3

EDIT2:

Решение с двойным cumsum:

np.random.seed(1)
df = pd.DataFrame([4,0,4,7,4], index=[1,2,2,3,4])
print (df)
   0
1  4
2  0
2  4
3  7
4  4

mask = (df[0] == 0).cumsum().cumsum()
print (mask)
1    0
2    1
2    2
3    3
4    4
Name: 0, dtype: int32

df.loc[mask == 1, 0] = 200
print (df)
     0
1    4
2  200
2    4
3    7
4    4

Ответ 3

Рассмотрим блок данных df

df = pd.DataFrame(dict(A=[1, 2, 3, 4, 5]))

print(df)

   A
0  1
1  2
2  3
3  4
4  5

Создайте произвольный фрагмент slc

slc = df[df.A > 2]

print(slc)

   A
2  3
3  4
4  5

Доступ к первой строке slc внутри df с помощью index[0] и loc

df.loc[slc.index[0]] = 0
print(df)

   A
0  1
1  2
2  0
3  4
4  5

Ответ 4

import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.rand(6,1),index=[1,2,2,3,3,3])
df[1] = 0
df.columns=['a','b']
df['b'][df['a']>=0.5]=1
df=df.sort(['b','a'],ascending=[0,1])
df.loc[df[df['b']==0].index.tolist()[0],'a']=0

В этом методе дополнительная копия dataframe не создается, но вводится дополнительный столбец, который можно отбросить после обработки. Чтобы выбрать любой индекс, а не первый, вы можете изменить последнюю строку следующим образом

df.loc[df[df['b']==0].index.tolist()[n],'a']=0

чтобы изменить любой n-й элемент в срезе

DF

          a  
1  0.111089  
2  0.255633  
2  0.332682  
3  0.434527  
3  0.730548  
3  0.844724  

df после нарезки и маркировки их

          a  b
1  0.111089  0
2  0.255633  0
2  0.332682  0
3  0.434527  0
3  0.730548  1
3  0.844724  1

После изменения значения первого элемента в срезе (с пометкой 0) до 0

          a  b
3  0.730548  1
3  0.844724  1
1  0.000000  0
2  0.255633  0
2  0.332682  0
3  0.434527  0