Найти общие значения в столбце, содержащем список элементов - PullRequest
0 голосов
/ 01 октября 2018

У меня есть набор данных, который содержит несколько столбцов, которые представляют собой список элементов.Я привел пример ниже.Я пытаюсь найти записи, которые имеют элементы в списке со 100% соответствием.Я хотел бы найти те, которые имеют 90% или ниже.

>>> df2 = pd.DataFrame({ 'ID':['1', '2', '3', '4', '5', '6', '7', '8'], 'Productdetailed': [['Phone', 'Watch', 'Pen'], ['Pencil', 'fork', 'Eraser'], ['Apple', 'Mango', 'Orange'], ['Something', 'Nothing', 'Everything'], ['Eraser', 'fork', 'Pencil'], ['Phone', 'Watch', 'Pen'],['Apple', 'Mango'], ['Pen', 'Phone', 'Watch']]})

>>> df2
ID                   Productdetailed
0  1               [Phone, Watch, Pen]
1  2            [Pencil, fork, Eraser]
2  3            [Apple, Mango, Orange]
3  4  [Something, Nothing, Everything]
4  5            [Eraser, fork, Pencil]
5  6               [Phone, Watch, Pen]
6  7                    [Apple, Mango]
7  8               [Pen, Phone, Watch]

Если вы заметили индекс 0 и индекс 7 в df2, то есть один и тот же набор предметов, но в другом порядке.Где в индексах 0 и 5 есть одинаковые элементы в одинаковом порядке.Я хотел бы считать их обоих совпадением.Я пробовал groupby и series.isin().Я также попробовал пересечение, разделив набор данных на две части, но он завершился неудачно с ошибкой типа.

Сначала я хотел бы посчитать количество точно совпадающих элементов (количество найденных совпадений строк) вместе с порядковыми номерами строк.это соответствует.Но когда есть элементы, которые имеют только частичное совпадение, например, индекс 2 и индекс 6 в df2.Я хотел бы сказать, процент элементов, которые соответствуют и с какими номерами столбцов.

Я упоминал.Я попытался разбить данные по конкретному значению столбца на две части.Тогда

applied df2['Intersection'] = 
     [list(set(a).intersection(set(b))) 
         for a, b in zip(df2_part1.Productdetailed, df2_part2.Productdetailed)
     ]

, где a и b - это столбец Productdetailed из обломков df2_part1 и df2_part2.

Есть ли способ сделатьэтот?Пожалуйста, помогите

Ответы [ 2 ]

0 голосов
/ 01 октября 2018

Чтобы узнать точное совпадение:

df2["Productdetailed"]=df2["Productdetailed"].sort_values()
# create new colum from the sorted list. More easy to work with pivot table
df2['Productdetailed_str'] = df2['Productdetailed'].apply(lambda x: ', '.join(x))
df2["hit"] = 1
df3 = (df2.pivot_table(index=["Productdetailed_str"],
                 values=["ID", "hit"],
                aggfunc={'ID': lambda x: ', '.join(x), 'hit': 'sum'}
               ))

Хит - это число вхождений.результат df3:

                                  ID  hit
Productdetailed_str                      
Apple, Mango                       7    1
Apple, Mango, Orange               3    1
Eraser, fork, Pencil               5    1
Pen, Phone, Watch                  8    1
Pencil, fork, Eraser               2    1
Phone, Watch, Pen               1, 6    2
Something, Nothing, Everything     4    1

Частичное совпадение сложнее, но вы можете начать разбивать список и играть с сводной таблицей:

test = df2.apply(lambda x: pd.Series(x['Productdetailed']),axis=1).stack().reset_index(level=1, drop=True).to_frame(name='list').join(df2)

Если вы запустите тест.В «столбце списка» есть слово из списка «Столбец продукта».Кроме того, у вас есть идентификатор ... так что я думаю, что с помощью сводной таблицы вы можете извлечь информацию ..

0 голосов
/ 01 октября 2018

Это решение решает задачу точного соответствия (сложность кода очень высока и не рекомендуется):

#First create a dummy column of Productdetailed which is sorted
df2['dummy'] = df2['Productdetailed'].apply(sorted)
#Create Matching column which stores index of first matched list
df2['Matching'] = np.nan

#Code for finding the exact matches and assigning indices in Matching column
for index1,lst1 in enumerate(df2['dummy']):
    for index2,lst2 in enumerate(df2['dummy']):
        if index1<index2:
            if (lst1 == lst2):
                if np.isnan(df2.loc[index2,'Matching']):
                    df2.loc[index1,'Matching'] = index1
                    df2.loc[index2,'Matching'] = index1

#Finding the sum of total exact matches
print(df2['Matching'].notnull().sum())
5

#Deleting the dummy column
del df2['dummy']

#Final Dataframe
print(df2)

  ID                   Productdetailed  Matching
0  1               [Phone, Watch, Pen]       0.0
1  2            [Pencil, fork, Eraser]       1.0
2  3            [Apple, Mango, Orange]       NaN
3  4  [Something, Nothing, Everything]       NaN
4  5            [Eraser, fork, Pencil]       1.0
5  6               [Phone, Watch, Pen]       0.0
6  7                    [Apple, Mango]       NaN
7  8               [Pen, Phone, Watch]       0.0

Для использования как с полным, так и с частичным совпадением (если совпадения по крайней мере с двумя значениями, то это совпадение частично, также может быть изменен):

#First create a dummy column of Productdetailed which is sorted
df2['dummy'] = df2['Productdetailed'].apply(sorted)
#Create Matching column which stores index of first matched list
df2['Matching'] = np.nan
#Create Column Stating Status of Matching
df2['Status'] = 'No Match'

#Code for finding the exact matches and assigning indices in Matching column
for index1,lst1 in enumerate(df2['dummy']):
    for index2,lst2 in enumerate(df2['dummy']):
        if index1<index2:
            if (lst1 == lst2):
                if np.isnan(df2.loc[index2,'Matching']):
                    df2.loc[index1,'Matching'] = index1
                    df2.loc[index2,'Matching'] = index1
                    df2.loc[[index1,index2],'Status'] = 'Fully Matched'
            else:
                count = sum([1 for v1 in lst1 for v2 in lst2 if v1==v2])
                if count>=2:
                    if np.isnan(df2.loc[index2,'Matching']):
                        df2.loc[index1,'Matching'] = index1
                        df2.loc[index2,'Matching'] = index1
                        df2.loc[[index1,index2],'Status'] = 'Partially Matched'

#Finding the sum of total exact matches
print(df2['Matching'].notnull().sum())

7

#Deleting the dummy column
del df2['dummy']

#Final Dataframe
print(df2)

  ID                   Productdetailed  Matching             Status
0  1               [Phone, Watch, Pen]       0.0      Fully Matched
1  2            [Pencil, fork, Eraser]       1.0      Fully Matched
2  3            [Apple, Mango, Orange]       2.0  Partially Matched
3  4  [Something, Nothing, Everything]       NaN           No Match
4  5            [Eraser, fork, Pencil]       1.0      Fully Matched
5  6               [Phone, Watch, Pen]       0.0      Fully Matched
6  7                    [Apple, Mango]       2.0  Partially Matched
7  8               [Pen, Phone, Watch]       0.0      Fully Matched
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...