Как найти наиболее часто встречающуюся пару значений?

Есть датафрейм, в котором по колонкам разбросаны данные строкового типа.

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

Пример:

data={'1':['ball', 'pen', 'pencil', 'paper', 'mug',None,None,None,None],
      '2':['notebook', 'pen', 'computer', 'paper', 'desk',None,None,None,None],
      '3':['ball', 'notebook', 'pen','pencil', 'paper', 'mug',None,None,None],
      '4':['ball','notebook',None,None,None,None,None,None,None], 
      '5':['computer','ball', 'pen', 'pencil', 'paper', 'mug','notebook','pipe','tube']}
dat=pd.DataFrame(data)
dat

Задача получить на выходе значения 'pen' и 'paper'.


Ответы (2 шт):

Автор решения: CrazyElf

Наверняка можно как-то проще, но я не нашёл другого способа "склеить" колонки датафрейма в один сплошной список:

pd.DataFrame(dat.values.flatten()).value_counts()

Вывод:

pen         4
paper       4
notebook    4
ball        4
pencil      3
mug         3
computer    2
tube        1
pipe        1
desk        1
dtype: int64

Но вообще тут наиболее часто (по 4 раза) встречаются 4 слова, а не 2.

UPDATE: переделал на сочетания из двух слов в каждом отдельном столбце

import pandas as pd
from itertools import combinations
from collections import Counter

data={'1':['ball', 'pen', 'pencil', 'paper', 'mug',None,None,None,None],
      '2':['notebook', 'pen', 'computer', 'paper', 'desk',None,None,None,None],
      '3':['ball', 'notebook', 'pen','pencil', 'paper', 'mug',None,None,None],
      '4':['ball','notebook',None,None,None,None,None,None,None], 
      '5':['computer','ball', 'pen', 'pencil', 'paper', 'mug','notebook','pipe','tube']}
dat=pd.DataFrame(data)

counter = Counter()
dat.apply(lambda x: counter.update(combinations(x[~x.isna()].values, 2)))
print(counter.most_common(1))

Вывод:

[(('pen', 'paper'), 4)]

Если посмотреть все сочетания из counter.most_common(), то тут уже да, 4 раза только эти слова сочетаются, а остальные 3 раза и меньше.

[(('pen', 'paper'), 4), (('ball', 'pen'), 3), (('ball', 'pencil'), 3), ...
→ Ссылка
Автор решения: MaxU

Можно воспользоваться методом Series.mode():

In [39]: dat.stack().mode()
Out[39]:
0        ball
1    notebook
2       paper
3         pen
dtype: object
→ Ссылка