Удаление дубликатов, включенных в два столбца в pandas

#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.