如何为 size() 列分配名称?

Posted

技术标签:

【中文标题】如何为 size() 列分配名称?【英文标题】:How to assign a name to the size() column? 【发布时间】:2013-08-02 10:23:50 【问题描述】:

我在 groupby 结果上使用.size() 以计算每个组中有多少项目。

我希望将结果保存到一个新的列名而不手动编辑列名数组,怎么做?

这是我尝试过的:

grpd = df.groupby(['A','B'])
grpd['size'] = grpd.size()
grpd

我得到的错误:

TypeError: 'DataFrameGroupBy' 对象不支持项目分配 (在第二行)

【问题讨论】:

值得注意的是,size 不是一个列的选择,因为它是 pandas 下每个对象的内置方法,因此您只能通过 getitem 而不是通过 getattr 检索它。 【参考方案1】:

df.groupby(...) 的结果不是 DataFrame。要取回 DataFrame,您必须对每个组应用一个函数、转换组的每个元素或过滤组。

您似乎想要一个 DataFrame,其中包含 (1) df 中的所有原始数据和 (2) 每组中有多少数据的计数。这些东西有不同的长度,所以如果它们需要进入同一个 DataFrame,你需要冗余地列出大小,即每个组中的每一行。

df['size'] = df.groupby(['A','B']).transform(np.size)

(顺便说一句:如果您可以显示简洁的示例输入和预期结果,这将很有帮助。)

【讨论】:

我还发现这几乎相等(创建一个新的数据框),但不确定它与您的解决方案在效率方面的比较***.com/questions/10373660/… 您的解决方案在玩具示例上运行良好,但在实际数据上返回错误pastebin.com/aCsMxCd5 在 pandas 20.3 中,@jezraels 的 df['size'] = df.groupby(['A','B']) .A .transform(np.size) 有效;如果没有.A,你会得到“ValueError:错误的项目数量传递了 2,位置意味着 1”,即“有 2 列,需要 1”。 @denis 非常感谢您的评论!【参考方案2】:

你需要transform size - lendf 和以前一样:

注意:

这里需要在groupby 后面加一列,否则会报错。因为GroupBy.size也算NaNs,所以使用什么列并不重要。所有列的工作方式相同。

import pandas as pd

df = pd.DataFrame('A': ['x', 'x', 'x','y','y']
                , 'B': ['a', 'c', 'c','b','b'])
print (df)
   A  B
0  x  a
1  x  c
2  x  c
3  y  b
4  y  b

df['size'] = df.groupby(['A', 'B'])['A'].transform('size')
print (df)
   A  B  size
0  x  a     1
1  x  c     2
2  x  c     2
3  y  b     2
4  y  b     2

如果需要在df 的聚合df - len 中设置列​​名显然与以前相同:

import pandas as pd

df = pd.DataFrame('A': ['x', 'x', 'x','y','y']
                , 'B': ['a', 'c', 'c','b','b'])
print (df)
   A  B
0  x  a
1  x  c
2  x  c
3  y  b
4  y  b

df = df.groupby(['A', 'B']).size().reset_index(name='Size')
print (df)
   A  B  Size
0  x  a     1
1  x  c     2
2  y  b     2

【讨论】:

不错的一个。但是如果我有多个索引,我该如何做与df.groupby(['A', 'B']).size().reset_index(name='Size') 相同的操作? @Sotos 如果使用最新版本的 pandas,方法相同。 类似...reset_index('V1', name = 'size')? @Sotos 嗯,这样不行。需要.reset_index().rename(columns='index':'col', 'anothercol':'col2') 这正是我最后所做的...(full_df .set_index('cdatetime') .groupby(['Cluster', 'source', 'action', pd.Grouper(freq = 'H', sort = True)]) .size() .reset_index(['Cluster', 'source', 'action']) .rename(columns=0: 'cnt') )【参考方案3】:

DataFrameGroupBy 对象的.size() 内置方法实际上返回一个具有组大小的 Series 对象,而不是 DataFrame。如果您想要一个 DataFrame,其列是组大小,由组索引,具有自定义名称,您可以使用 .to_frame() 方法并使用所需的列名称作为其参数。

grpd = df.groupby(['A','B']).size().to_frame('size')

如果您希望组再次成为列,您可以在末尾添加 .reset_index()

【讨论】:

【参考方案4】:

可以说 n 是数据框的名称,而 cst 是重复的项目数。 下面的代码给出了下一列的计数

cstn=Counter(n.cst)
cstlist = pd.DataFrame.from_dict(cstn, orient='index').reset_index()
cstlist.columns=['name','cnt']
n['cnt']=n['cst'].map(cstlist.loc[:, ['name','cnt']].set_index('name').iloc[:,0].to_dict())

希望这会奏效

【讨论】:

【参考方案5】:

您可以将groupby中的as_index参数设置为False以获取DataFrame而不是Series:

df = pd.DataFrame('A': ['a', 'a', 'b', 'b'], 'B': [1, 2, 2, 2])

df.groupby(['A', 'B'], as_index=False).size()

输出:

   A  B  size
0  a  1     1
1  a  2     1
2  b  2     2

【讨论】:

以上是关于如何为 size() 列分配名称?的主要内容,如果未能解决你的问题,请参考以下文章

我应该如何为精灵表中的精灵分配名称?

如何为Dataframe一列分配不同的数字[重复]

如果没有插入值,如何为 SQL Server 中的列字段分配唯一值?

如何为R中向量的特定元素分配名称

如何为 TPL 中的任务分配名称

分发键如何为GreenPlum分段分配数据