#python #pandas
Вопрос:
У меня есть фрейм данных, который имеет два столбца. Я хочу удалить строки таким образом, чтобы для каждой строки она включала только один экземпляр в первом столбце, но включала все уникальные значения во втором столбце.
Вот пример:
data = [[1,100],
[1,101],
[1,102],
[1,103],
[2,102],
[2,104],
[2,105],
[3,102],
[3,107]]
df = pd.DataFrame(data,columns = ['x', 'y'])
Фрейм данных выглядит следующим образом:
x y
0 1 100
1 1 101
2 1 102
3 1 103
4 2 102
5 2 104
6 2 105
7 3 102
8 3 107
Выходной фрейм данных будет выглядеть следующим образом:
x y inc
0 1 100 1
1 1 101 0
2 1 102 0
3 1 103 0
4 2 102 1
5 2 104 0
6 2 105 0
7 3 102 0
8 3 107 1
таким образом, строка 0 будет включена (inc), поскольку 1 еще не была продублирована в столбце x. Строки 1-3 будут исключены, поскольку 1 в столбце x уже учтен. Строка 4 будет включена, так как 2 в столбце x еще не были включены, а столбец y (102) не был включен (он был исключен как дубликат). В строке 7 первый экземпляр 3 в столбце x будет исключен, поскольку 102 (в столбце y) уже учитывались в строке 4. Поэтому мы бы перешли к строке 8 и включили ее.
Я пробовал различные .duplicated
подходы, но ни один из них до сих пор не работал. Если вы берете только первый экземпляр значения в столбце x, вы исключаете строки, которые должны быть включены (например, строка 7).
Любая помощь будет оценена.
Комментарии:
1. Я думаю, что просто
for
цикл подойдет.2. Я пытался придумать способ сделать это без цикла, но это может быть лучшим (единственным) вариантом.
Ответ №1:
Один из способов — использовать set
и создать пользовательскую функцию:
seen = set()
def func(d):
res = d[~d.isin(seen)]
if len(res):
cur = res.iat[0]
seen.add(cur)
return cur
print (df.groupby("x")["y"].apply(func))
x
1 100
2 102
3 107
Name: y, dtype: int64
Ответ №2:
Я полагаю, вы бы просто использовали drop_duplicates
с подмножеством 'x'
и указали 'first'
, какие строки будут сохранены.
df.drop_duplicates(keep='first', subset = 'x')
https://pandas.pydata.org/docs/reference/api/pandas .DataFrame.drop_duplicates.html
Комментарии:
1. Это не то, чего хочет OP.
2. Это приводит к сохранению строки 7 и удалению строки 8.