python pandas

python - Contando la combinación más común de valores en la columna del marco de datos



pandas (5)

Otro truco con la función itertools.combinations :

from itertools import combinations import pandas as pd test_df = ... # your df counts_df = test_df.groupby(''ID'')[''Product''].agg(lambda x: list(combinations(x, 2)))/ .apply(pd.Series).stack().value_counts().to_frame()/ .reset_index().rename(columns={''index'': ''Combination'', 0:''Count''}) print(counts_df)

La salida:

Combination Count 0 (A, B) 2 1 (A, C) 1 2 (A, D) 1 3 (C, D) 1

Tengo DataFrame en la siguiente forma:

ID Product 1 A 1 B 2 A 3 A 3 C 3 D 4 A 4 B

Me gustaría contar la combinación más común de dos valores de la columna Product agrupada por ID . Entonces, para este ejemplo, el resultado esperado sería:

Combination Count A-B 2 A-C 1 A-D 1 C-D 1

¿Es posible esta salida con pandas?


Podemos merge dentro de ID y filtrar fusiones duplicadas (supongo que tiene un RangeIndex predeterminado). Luego ordenamos para que la agrupación sea independientemente del orden:

import pandas as pd import numpy as np df1 = df.reset_index() df1 = df1.merge(df1, on=''ID'').query(''index_x > index_y'') df1 = pd.DataFrame(np.sort(df1[[''Product_x'', ''Product_y'']].to_numpy(), axis=1)) df1.groupby([*df1]).size()

0 1 A B 2 C 1 D 1 C D 1 dtype: int64


Puede usar combinations de itertools junto con groupby y apply

from itertools import combinations def get_combs(x): return pd.DataFrame({''Combination'': list(combinations(x.Product.values, 2))})

(df.groupby(''ID'').apply(get_combs) .reset_index(level=0) .groupby(''Combination'') .count() )

ID Combination (A, B) 2 (A, C) 1 (A, D) 1 (C, D) 1


Usando itertools y Counter .

import itertools from collections import Counter agg_ = lambda x: tuple(itertools.combinations(x, 2)) product = list(itertools.chain(*df.groupby(''ID'').agg({''Product'': lambda x: agg_(sorted(x))}).Product)) # You actually do not need to wrap product with list. The generator is ok counts = Counter(product)

Salida

Counter({(''A'', ''B''): 2, (''A'', ''C''): 1, (''A'', ''D''): 1, (''C'', ''D''): 1})

También puede hacer lo siguiente para obtener un marco de datos

pd.DataFrame(list(counts.items()), columns=[''combination'', ''count'']) combination count 0 (A, B) 2 1 (A, C) 1 2 (A, D) 1 3 (C, D) 1


Utilice itertools.combinations , explode y value_counts

import itertools (df.groupby(''ID'').Product.agg(lambda x: list(itertools.combinations(x,2))) .explode().str.join(''-'').value_counts()) Out[611]: A-B 2 C-D 1 A-D 1 A-C 1 Name: Product, dtype: int64

O:

import itertools (df.groupby(''ID'').Product.agg(lambda x: list(map(''-''.join, itertools.combinations(x,2)))) .explode().value_counts()) Out[597]: A-B 2 C-D 1 A-D 1 A-C 1 Name: Product, dtype: int64