Подсчитайте уникальные имена 2 разных столбцов в pandas pandas

avatar
Gonzalo Etse
1 июля 2021 в 16:13
54
2
1

У меня есть набор данных с именами, отображаемыми в двух столбцах (player1_name и player2_name могут иметь одних и тех же игроков в разных строках):

Player1_name player2_name Место
Каспаров Б.Фишер Париж
Каруна Уэсли.Со Токио
Накамура Каспаров С.Петербург
Каруна Накамура Нью-Йорк

Если бы это была таблица, я бы хотел получить следующее:

Kasparov 2
Caruna 2
Nakamura 2
Wesley.So 1
B. Fisher 1

В основном, value_counts() из 2 объединенных столбцов. Я предполагаю, что это довольно просто, но я не могу понять

Источник

Ответы (2)

avatar
Anurag Dabas
1 июля 2021 в 16:16
2

Попробуйте:

out=df.melt(None,['PLayer1_name','player2_name'])['value'].value_counts()

ИЛИ

out=df[['PLayer1_name','player2_name']].stack().droplevel(1).value_counts()

вывод out:

Kasparov     2
Nakamura     2
Caruna       2
Wesley.So    1
B.Fisher     1
dtype: int64
avatar
Henry Ecker
1 июля 2021 в 16:38
2

np.unique с return_counts=True может работать лучше, поскольку не требует изменения формы:

values, counts = np.unique(df[['PLayer1_name', 'player2_name']],
                           return_counts=True)
s = pd.Series(counts, index=values).sort_values(ascending=False)

s:

Caruna       2
Kasparov     2
Nakamura     2
B.Fisher     1
Wesley.So    1
dtype: int64

Некоторая информация о времени:

import numpy as np
import pandas as pd

df_ = pd.DataFrame({
    'PLayer1_name': {0: 'Kasparov', 1: 'Caruna', 2: 'Nakamura', 3: 'Caruna'},
    'player2_name': {0: 'B.Fisher', 1: 'Wesley.So', 2: 'Kasparov',
                     3: 'Nakamura'},
    'Place': {0: 'Paris', 1: 'Tokyo', 2: 'S.Petersburg', 3: 'New York'}
})

Этот ответ:

def fn(df):
    values, counts = np.unique(df[['PLayer1_name', 'player2_name']],
                               return_counts=True)
    return pd.Series(counts, index=values).sort_values(ascending=False)

%timeit fn(df_)
640 µs ± 13.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Опция расплава Анурага Дабаса:

def fn2(df):
    return df.melt(
        None, ['PLayer1_name', 'player2_name']
    )['value'].value_counts()

%timeit fn2(df_)
2.05 ms ± 203 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Опция стека Анурага Дабаса:

def fn3(df):
    return (
        df[['PLayer1_name', 'player2_name']].stack()
            .droplevel(1).value_counts()
    )

%timeit fn3(df_)
1.32 ms ± 51.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Camilo Martinez M.
1 июля 2021 в 16:48
0

Я бы всегда выбирал такой вариант, как этот, не только из-за скорости, но и потому, что интуитивно понятно, что происходит за листами.

Henry Ecker
1 июля 2021 в 16:51
0

В любом подходе всегда есть плюсы и минусы. Но в этом случае я думаю, что numpy лучше всего.