Панды: Группировка по комбинации двух столбцов в Пандах 0.23.4 - PullRequest
0 голосов
/ 03 декабря 2018

Я довольно новичок в Python.Я наткнулся на Панд: Группировать по комбинации двух столбцов на SO.К сожалению, принятый ответ больше не работает с версией pandas 0.23.4 Цель этого поста - определить комбинацию групповых переменных и создать словарь для значений.то есть group_by должен игнорировать порядок группировки.

Вот принятый ответ:

import pandas as pd
from collections import Counter

d = pd.DataFrame([('a','b',1), ('a','c', 2), ('b','a',3), ('b','a',3)],
                 columns=['x', 'y', 'score'])

d[['x', 'y']] = d[['x', 'y']].apply(sorted, axis=1)
x = d.groupby(['x', 'y']).agg(Counter)
print(x)

Здесь ...apply(sorted) выдает следующее исключение:

повысить ValueError («Должны иметь равные ключи и значение len» ValueError: Должны иметь равные ключи и значение len при установке с итеративным

Вот моя версия для панд:

> pd.__version__
Out: '0.23.4'

Вотто, что я пробовал после прочтения https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.sort_values.html:

d = pd.DataFrame([('a','b',1), ('a','c', 2), ('b','a',3), ('b','a',3)],
                 columns=['x', 'y', 'score'])

d=d.sort_values(by=['x','y'],axis=1).reset_index(drop=True)
x = d.groupby(['x', 'y']).agg(Counter)
print(x)

К сожалению, это также выдает ошибку:

1382, в _get_label_or_level_values ​​поднять KeyError (ключ) KeyError: 'x'

Ожидаемый результат:

        score           count
x   y                     
a   b   {1: 1, 3: 2}      2
    c   {2: 1}            1 

Кто-нибудь может мне помочь? На заметку, было бы здорово, если бы вы также могли подсказать, как вычислить счетkeys() в столбце score. Я ищу векторизованное решение.

Я использую python 3.6.7

Большое спасибо.

Ответы [ 3 ]

0 голосов
/ 03 декабря 2018

Использование -

a=d[['x','y']].values
a.sort(axis=1)
d[['x','y']] = a
x = d.groupby(['x', 'y']).agg(Counter)
print(x)

Выход

            score
x y              
a b  {1: 1, 3: 2}
  c        {2: 1}
0 голосов
/ 03 декабря 2018

Добавление result_type = 'broadcast' в качестве одного из аргументов для .apply() сработало.

>>> d = pd.DataFrame([('a','b',1), ('a','c', 2), ('b','a',3), ('b','a',3)],
             columns=['x', 'y', 'score'])
>>> d[['x', 'y']] = d[['x', 'y']].apply(sorted, axis=1, result_type='broadcast')
>>> x = d.groupby(['x', 'y']).agg(Counter)
>>> print(x)

            score
x y              
a b  {1: 1, 3: 2}
  c        {2: 1}

Обратите внимание на разницу с result_type = 'broadcast'.

>>> d[['x', 'y']].apply(sorted, axis=1)

0    [a, b]
1    [a, c]
2    [a, b]
3    [a, b]
dtype: object

>>> d[['x', 'y']].apply(sorted, axis=1, result_type='broadcast')

   x  y
0  a  b
1  a  c
2  a  b
3  a  b

., result_type = 'broadcast' разбивает ( широковещательные сообщения ) результат возврата .apply() из списка в соответствующие столбцы, что позволяет присваивать значение d[['x', 'y']].

0 голосов
/ 03 декабря 2018

Проблема в sorted возвращаемых списках, поэтому необходимо преобразовать ti в Series:

d[['x', 'y']] = d[['x', 'y']].apply(lambda x: pd.Series(sorted(x)), axis=1)

Но быстрее использовать numpy.sort с конструктором DataFrame, потому чтоapply - это циклы под капотом:

d = pd.DataFrame([('a','b',1), ('a','c', 2), ('b','a',3), ('b','a',3)],
                 columns=['x', 'y', 'score'])

d[['x', 'y']] = pd.DataFrame(np.sort(d[['x', 'y']], axis=1), index=d.index)

Затем выберите столбец для агрегирования со списком агрегированных функций - например, nunique для подсчета количества уникальных значений:

x = d.groupby(['x', 'y'])['score'].agg([Counter, 'nunique'])
print(x)
          Counter  nunique
x y                       
a b  {1: 1, 3: 2}        2
  c        {2: 1}        1

Или считать DataFrameGroupBy.size:

x = d.groupby(['x', 'y'])['score'].agg([Counter, 'size'])
print(x)
          Counter  size
x y                    
a b  {1: 1, 3: 2}     3
  c        {2: 1}     1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...