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

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

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

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

РЕДАКТИРОВАТЬ: кажется, есть два способа, используя маску или IdxMax. Кажется, что метод IdxMax работает, если ваш индекс уникален, а метод маски - если нет. В моем случае индекс не уникален, о чем я забыл упомянуть в первоначальном посте.

4 ответа

Решение

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

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

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

Я думаю, что вы можете использовать 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

РЕДАКТИРОВАТЬ:

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

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

Рассмотрим кадр данных 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
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

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

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

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

Д.Ф.

          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
Другие вопросы по тегам