Pandas dataframe: удалить вторичное предстоящее то же значение - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть фрейм данных:

col1  col2
 a     0
 b     1
 c     1
 d     0
 c     1
 d     0

Вкл. 'col2' Я хочу оставить только первый 1 сверху и заменить каждый 1 ниже первого на 0,такой, что вывод:

col1  col2
 a     0
 b     1
 c     0
 d     0
 c     0
 d     0

Большое спасибо.

Ответы [ 8 ]

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

Ооочень много вариантов, вот мой ... почти такой же, как у тимбебса (найден независимо), но все же другой;)

Найдите индекс col2, который имеет первое вхождение в 1, и изменитевсе значения строки после этого индекса до 0:

df['col2'].iloc[df.col2.idxmax()+1:] = 0
0 голосов
/ 06 декабря 2018
id = list(df["col2"]).index(1)
df.iloc[id+1:]["col2"].replace(1,0,inplace=True)
0 голосов
/ 06 декабря 2018

np.flatnonzero

Потому что я думал, что нам нужно больше ответов

df.loc[df.index[np.flatnonzero(df.col2)[1:]], 'col2'] -= 1
df

  col1  col2
0    a     0
1    b     1
2    c     0
3    d     0
4    c     0
5    d     0

То же самое, но чуть более подлый.

df.col2.values[np.flatnonzero(df.col2.values)[1:]] -= 1
df

  col1  col2
0    a     0
1    b     1
2    c     0
3    d     0
4    c     0
5    d     0
0 голосов
/ 06 декабря 2018

Мне это тоже нравится

data['col2'][np.where(data['col2'] == 1)[0][0]+1:] = 0
0 голосов
/ 06 декабря 2018

Использование drop_duplicates с reindex

df.col2=df.col2.drop_duplicates().reindex(df.index,fill_value=0)
df
Out[1078]: 
  col1  col2
0    a     0
1    b     1
2    c     0
3    d     0
4    c     0
5    d     0
0 голосов
/ 06 декабря 2018

Вы можете использовать numpy для эффективного решения:

a = df.col2.values
b = np.zeros_like(a)
b[a.argmax()] = 1
df.assign(col2=b)

  col1  col2
0    a     0
1    b     1
2    c     0
3    d     0
4    c     0
5    d     0
0 голосов
/ 06 декабря 2018

Случай 1 : df имеет только единицы и нули в col2 и целочисленные индексы.

>>> df
  col1  col2
0    a     0
1    b     1
2    c     1
3    d     0
4    c     1
5    d     0

Вы можете использовать:

>>> df.loc[df['col2'].idxmax() + 1:, 'col2'] = 0
>>> df
  col1  col2
0    a     0
1    b     1
2    c     0
3    d     0
4    c     0
5    d     0

Case2 : df может иметь все виды значений в столбце col2 и иметь целочисленные индексы.

>>> df # demo dataframe
  col1  col2
0    a     0
1    b     1
2    c     2
3    d     2
4    c     3
5    d     3

Можно использовать:

>>> df.loc[(df['col2'] == 1).idxmax() + 1:, 'col2'] = 0
>>> df
  col1  col2
0    a     0
1    b     1
2    c     0
3    d     0
4    c     0
5    d     0

Случай 3 : df может иметь все виды значений в столбце col2 и иметь произвольный индекс.

>>> df
  col1  col2
u    a    -1
v    b     1
w    c     2
x    d     2
y    c     3
z    d     3

Вы можете использовать:

>>> df['col2'].iloc[(df['col2'].values == 1).argmax() + 1:] = 0
>>> df
  col1  col2
u    a    -1
v    b     1
w    c     0
x    d     0
y    c     0
z    d     0
0 голосов
/ 06 декабря 2018

Вы можете найти индекс первого 1 и установить для других значение 0:

mask = df['col2'].eq(1)
df.loc[mask & (df.index != mask.idxmax()), 'col2'] = 0

Для повышения производительности см. Эффективно вернуть индекс первого значения, удовлетворяющего условию, вмассив .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...