如何为 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
- len
的df
和以前一样:
注意:
这里需要在groupby
后面加一列,否则会报错。因为GroupBy.size
也算NaN
s,所以使用什么列并不重要。所有列的工作方式相同。
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() 列分配名称?的主要内容,如果未能解决你的问题,请参考以下文章