Как найти первую строку после нескольких повторяющихся строк?

Мой DataFrame:

import pandas as pd
df = pd.DataFrame(
    {
        'x': ['a', 'a', 'a','b', 'b','c', 'c', 'c',],
        'y': list(range(8))
    }
)

И это ожидаемый результат. Я хочу создать столбец z:

   x  y    z
0  a  0    NaN
1  a  1    NaN 
2  a  2    NaN
3  b  3    3
4  b  4    NaN
5  c  5    NaN
6  c  6    NaN
7  c  7    NaN

Логика такова:

Я хочу найти первую строку после первой группы повторяющихся строк. Например, в столбце x значение a — это первое повторяющееся значение. Я хочу найти одну строку после окончания значений a. А затем поместите y этой строки в столбец z.

Это моя попытка, которая не дала мне результата:

m = (df.x.duplicated())
out = df[m]

что, если бы был только один a? а если есть только?

mozway 20.06.2024 09:07

@mozway Спасибо за ответ. В моих данных a всегда дублируется.

AmirX 20.06.2024 09:08

То есть первое значение всегда a и всегда дублируется? оно тоже встречается только на одном участке или может повториться?

mozway 20.06.2024 09:09

@mozway да. Это именно мои данные. Если найду какой-то вариант, выложу. Спасибо. Ты покинул этот мир :)

AmirX 20.06.2024 09:11
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
4
81
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Один из вариантов с использованием пользовательской маски:

# flag rows after the first group
m = df['x'].ne(df['x'].iat[0]).cummax()

# pick the first one
out = df[m & ~m.shift(fill_value=False)]

Если ваше первое значение всегда a и вы хотите найти первое значение, отличное от a, вы также можете использовать:

m2 = df['x'].eq('a')

out = df[m2.shift(fill_value=False) & ~m2]

Или, если вы уверены, что после ведущих a есть хотя бы одна строка:

out = df.loc[[df['x'].ne('a').idxmax()]]

Выход:

   x  y
3  b  3

Некоторые промежуточные продукты (все подходы):

   x  y      m  ~m.shift(fill_value=False)     m2  m2.shift(fill_value=False)  df['x'].ne('a')
0  a  0  False                        True   True                       False            False
1  a  1  False                        True   True                        True            False
2  a  2  False                        True   True                        True            False
3  b  3   True                        True  False                        True             True
4  b  4   True                       False  False                       False             True
5  c  5   True                       False  False                       False             True
6  c  6   True                       False  False                       False             True
7  c  7   True                       False  False                       False             True
import pandas as pd
import numpy as np

df = pd.DataFrame({
    'x': ['a', 'a', 'a', 'b', 'b', 'c', 'c', 'c'],
    'y':  [10,20,30,40,50,60,70,80]
})
print(df)

x = df['x'].values
previous_elements = x[:-1]
next_elements = x[1:]

compare = previous_elements != next_elements

change_indicator = np.hstack([False,compare])

consecutive_dupes = np.diff(np.hstack([False,compare]))
print(consecutive_dupes)#[False False  True  True  True  True False]


true_indices = np.flatnonzero(consecutive_dupes[:-1] if any(consecutive_dupes) else None)
print(true_indices)#[2 3 4 5]

first_true_index = np.argmax( consecutive_dupes[:-1] if any(consecutive_dupes) else None )
print(first_true_index)#2
      
if first_true_index is not None :
    next_row_idx = first_true_index +1
    if next_row_idx < len(df):
       df.loc[next_row_idx, 'z'] = df.loc[next_row_idx,'y'] 
    
print(df)    
'''
  x   y     z
0  a  10   NaN
1  a  20   NaN
2  a  30   NaN
3  b  40  40.0
4  b  50   NaN
5  c  60   NaN
6  c  70   NaN
7  c  80   NaN
'''             

Другие вопросы по теме