Мой 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]
@mozway Спасибо за ответ. В моих данных a
всегда дублируется.
То есть первое значение всегда a
и всегда дублируется? оно тоже встречается только на одном участке или может повториться?
@mozway да. Это именно мои данные. Если найду какой-то вариант, выложу. Спасибо. Ты покинул этот мир :)
Один из вариантов с использованием пользовательской маски:
# 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
'''
что, если бы был только один a? а если есть только?