在Pandas中使用groupby + transform时,有没有.loc有什么区别

时间:2018-06-05 03:28:33

标签: pandas transform loc

我是python的新手。这是我的问题,这对我来说真的很奇怪。

简单的数据框如下所示:

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

我需要通过Hash对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 :(得分:3)

区别在于loc处理将DataFrame对象分配给单个列的方式。当您为DataFrame分配Card列时,它会尝试排列索引和列名称。列没有对齐,你得到NaN s。通过直接列访问进行分配时,它确定它是另一列的列,并且只是执行了它。

缩减为单列

您可以通过将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.factorizenp.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