Какая разница между с или без .loc при использовании groupby + transform в Pandas - PullRequest
0 голосов
/ 05 июня 2018

Я новичок в питоне.вот вопрос, который у меня есть, что действительно странно для меня.

Простой кадр данных выглядит следующим образом:

a1=pd.DataFrame({'Hash':[1,1,2,2,2,3,4,4],
                 'Card':[1,1,2,2,3,3,4,4]})

Мне нужно сгруппировать a1 по хэшу, подсчитать, сколько строк в каждомгруппу, затем добавьте один столбец в a1, чтобы указать номера строк.Итак, я хочу использовать groupby + transform.

Когда я использую:

a1['CustomerCount']=a1.groupby(['Hash']).transform(lambda x: x.shape[0])

Результат правильный:

   Card  Hash  CustomerCount
0     1     1              2
1     1     1              2
2     2     2              3
3     2     2              3
4     3     2              3
5     3     3              1
6     4     4              2
7     4     4              2

Но когда я использую:

a1.loc[:,'CustomerCount']=a1.groupby(['Hash']).transform(lambda x: x.shape[0])

Результат:

   Card  Hash  CustomerCount
0     1     1            NaN
1     1     1            NaN
2     2     2            NaN
3     2     2            NaN
4     3     2            NaN
5     3     3            NaN
6     4     4            NaN
7     4     4            NaN

Итак, почему это происходит?

Насколько я знаю, loc и iloc (как a1.loc [:,'CustomerCount']) лучше, чем ничего (например, a1 ['CustomerCount']), поэтому обычно рекомендуется использовать loc и iloc.Но почему это происходит?

Кроме того, я много раз пробовал loc и iloc для генерации нового столбца в одном фрейме данных.Они обычно работают.Так это как-то связано с groupby + transform?

1 Ответ

0 голосов
/ 05 июня 2018

Разница в том, как loc имеет дело с назначением объекта DataFrame одному столбцу.Когда вы присвоили DataFrame столбцам Card, он попытался выровнять индекс и имя столбца.Столбцы не выстроились в ряд, и вы получили NaN с.При назначении через прямой доступ к столбцу он определил, что это один столбец для другого, и только что сделал это.

Сократить до одного столбца

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

a1.loc[:,'CustomerCount'] = a1.groupby(['Hash']).Card.transform('size')
a1

   Hash  Card  CustomerCount
0     1     1              2
1     1     1              2
2     2     2              3
3     2     2              3
4     2     3              3
5     3     3              1
6     4     4              2
7     4     4              2

Переименовать столбец

На самом деле это не так, другой ответ гораздо проще

a1.loc[:, 'CustomerCount'] = a1.groupby('Hash').transform(len).rename(
    columns={'Card': 'CustomerCount'})
a1

pd.factorize и np.bincount

Что бы я на самом деле делал

f, u = pd.factorize(a1.Hash)
a1['CustomerCount'] = np.bincount(f)[f]
a1

Или встроенное копирование

a1.assign(CustomerCount=(lambda f: np.bincount(f)[f])(pd.factorize(a1.Hash)[0]))

   Hash  Card  CustomerCount
0     1     1              2
1     1     1              2
2     2     2              3
3     2     2              3
4     2     3              3
5     3     3              1
6     4     4              2
7     4     4              2
...