Подсчет совпадений и суммирование - PullRequest
0 голосов
/ 20 января 2020

Я хотел бы получить этот результат из этих двух фреймов данных

df1 = pd.DataFrame({'url': [
  'http://google.com/men', 
  'http://google.com/women', 
  'http://google.com/men-shoes',
  'http://google.com/women-shoes',
  'http://google.com/not-important',
], 'click': [3, 4, 6, 5, 8]})

df2 = pd.DataFrame({'keyword': ['men','women','shoes', 'kids']})

Результат:

  keyword  instances  clicks
0     men          2     9.0
1   women          2     9.0
2   shoes          2     11.0
3    kids          0     0.0

Который в основном подсчитывает, сколько раз любые ключевые слова df2 появляются на любом * Столбец 1008 * url затем объединить, чтобы проверить эти строки на совокупную сумму столбца click в df1

Я изо всех сил пытаюсь получить этот результат, спасибо.

Ответы [ 2 ]

1 голос
/ 20 января 2020

Вы можете попробовать это: он извлечет последнюю часть URL-адреса после / и разделит его на - (возможно, этого будет достаточно для вашего случая):

df1['keyword'] = df1['url'].str.extract(r'/([^/]+?)$')[0].str.split(r'-')
print( pd.merge(df1.explode('keyword'), df2, how='right')
         .groupby('keyword').agg({'click': 'sum', 'url': lambda x: x[~x.isna()].count()  })
         .rename(columns={'click': 'clicks', 'url':'instances'})
         .reset_index() )

Печать:

  keyword  clicks  instances
0    kids     0.0          0
1     men     9.0          2
2   shoes    11.0          2
3   women     9.0          2
1 голос
/ 20 января 2020

Вы можете использовать мою функцию fuzzy_merge, которую я написал, комбинируя ее с explode и groupby, мы достаточно близки к вашему результату, заметьте, что это все еще нечетко соответствие, поэтому есть разница.

Вы можете попробовать поиграть с аргументом threshold, чтобы получить желаемый результат:

mrg = (
    fuzzy_merge(df1, df2, 'url', 'keyword')
     .explode('matches')
     .groupby('matches').agg({'matches':'size',
                              'click':'sum'})
)

df2['instances'] = df2['keyword'].map(mrg['matches']).fillna(0)
df2['clicks'] = df2['keyword'].map(mrg['click']).fillna(0)

  keyword  instances  clicks
0     men        2.0     7.0
1   women        2.0     9.0
2   shoes        2.0    11.0
3    kids        0.0     0.0

Функция, используемая из связанного ответа:

from fuzzywuzzy import fuzz
from fuzzywuzzy import process

def fuzzy_merge(df_1, df_2, key1, key2, threshold=90, limit=2):
    """
    df_1 is the left table to join
    df_2 is the right table to join
    key1 is the key column of the left table
    key2 is the key column of the right table
    threshold is how close the matches should be to return a match, based on Levenshtein distance
    limit is the amount of matches that will get returned, these are sorted high to low
    """
    s = df_2[key2].tolist()

    m = df_1[key1].apply(lambda x: process.extract(x, s, limit=limit))    
    df_1['matches'] = m

    m2 = df_1['matches'].apply(lambda x: [i[0] for i in x if i[1] >= threshold])
    df_1['matches'] = m2

    return df_1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...