Быстрый способ найти дублирующуюся ячейку в определенном столбце фрейма данных в python-pandas?

#python #pandas #python-3.5

#python #pandas #python-3.5

Вопрос:

Учитывая фрейм данных df в следующей форме:

 item        attr
1           {1, 2, 3, 4}
2           {2, 4, 3, 2, 10}
3           {4, 37}
4           {1, 2, 3, 4}
  

Я хочу найти элемент-пару с таким же attr , например, item 1 и item 2 . Пожалуйста, обратите внимание, что df 200,000 элементы полностью. И я хочу самый быстрый способ их найти. Вы знаете, как это сделать? Заранее спасибо!

Комментарии:

1. attr это столбцы set s?

2. @juanpa.arrivillaga Да, это так

3.Как вы думаете, пара 3,4 с item 1,2 и 1,2 , 2,3 …. в item 1, 4 ?

4. Какой желаемый результат из образца?

5. @jezrael item Пары с одинаковыми attr , т.е. Набор которых одинаков, — это пары, которые я хочу найти. Так что в примере item 1 и item 4 должно быть найдено

Ответ №1:

Вы можете сначала преобразовать set в tuple , а затем aggregate nunique и unique . Последнее использование boolean indexing :

 df = pd.DataFrame({'item':[1,2,3,4],
                  'attr':[set({1, 2, 3, 4}),set({2, 4, 3, 2, 10}),
                          set({4, 37}), set({1, 2, 3, 4})]})

print (df)
            attr  item
0   {1, 2, 3, 4}     1
1  {3, 10, 2, 4}     2
2        {4, 37}     3
3   {1, 2, 3, 4}     4

df.attr = df.attr.apply(tuple)
print (df)
            attr  item
0   (1, 2, 3, 4)     1
1  (3, 10, 2, 4)     2
2        (4, 37)     3
3   (1, 2, 3, 4)     4

df1 = df.item.groupby(df['attr']).agg(['nunique', 'unique'])
df1 = df1[df1['nunique'] == 2]
print (df1)
              nunique  unique
attr                         
(1, 2, 3, 4)        2  [1, 4]
  

Другое решение, если в with есть только одно или пара значений DataFrame duplicated :

 df = pd.DataFrame({'item':[1,2,3,4],
                  'attr':[set({1, 2, 3, 4}),set({4, 37}),
                          set({4, 37}), set({1, 2, 3, 4})]})

print (df)
           attr  item
0  {1, 2, 3, 4}     1
1       {4, 37}     2
2       {4, 37}     3
3  {1, 2, 3, 4}     4

df.attr = df.attr.apply(tuple)


df1 = df[df.duplicated('attr', keep=False)]
df1 = df1.groupby('attr')['item'].apply(lambda x: x.tolist())
print (df1)
(1, 2, 3, 4)    [1, 4]
(4, 37)         [2, 3]
Name: item, dtype: object
  

РЕДАКТИРОВАТЬ с помощью комментария:

Использовать melt для изменения формы:

 df = pd.DataFrame({'item':[1,2,3,4,5],
                  'attr1':[set({1, 2, 3, 4}),set({4, 37}),set({4, 37}), 
                           set({1, 2, 3, 4}), set({4,8})],
                  'attr2':[set({1, 2 }),set({4, 37}),
                           set({4, 3}), set({1, 2}), set({4,8})]})

print (df)
          attr1    attr2  item
0  {1, 2, 3, 4}   {1, 2}     1
1       {4, 37}  {4, 37}     2
2       {4, 37}   {3, 4}     3
3  {1, 2, 3, 4}   {1, 2}     4
4        {8, 4}   {8, 4}     5

df = pd.melt(df, id_vars='item', value_name='attr').drop('variable', axis=1)
df.attr = df.attr.apply(tuple)
print (df)
   item          attr
0     1  (1, 2, 3, 4)
1     2       (4, 37)
2     3       (4, 37)
3     4  (1, 2, 3, 4)
4     5        (8, 4)
5     1        (1, 2)
6     2       (4, 37)
7     3        (3, 4)
8     4        (1, 2)
9     5        (8, 4)
  

Комментарии:

1. Спасибо за ваш ответ! Это здорово!

2. Но у меня все еще есть вопрос… Не могли бы вы, пожалуйста, сделать это более общим? Так что это также работает, когда имеется более одного столбца attr , например attr1 , и attr2 ?

3. set DataFrames неочевидны, поэтому этот ответ сложный. Я думаю, вам нужно изменить форму на один столбец attr , если столбцов больше attr1 , attr2 … а затем применить этот ответ.

4. Наконец, есть 66 пар одного и того же элемента. Но на самом деле я хочу найти 100 лучших похожих пар по сходству Джаккарда. Я думал, что среди 200 000 пар элементов есть более 100 одинаковых, но их нет. Есть ли у вас какая-либо идея быстро вычислить все сходства элементов?

5. Я думаю, вы можете создать новый вопрос, потому что в статистике я не могу вам очень хорошо помочь. К сожалению. 🙁