#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. Я думаю, вы можете создать новый вопрос, потому что в статистике я не могу вам очень хорошо помочь. К сожалению. 🙁