在 PandasGroupby 函数中重命名列名

Q1)我想做一个 groupby,SQL 风格的聚合和 重命名输出列:

示例数据集:

>>> df
ID     Region  count
0  100       Asia      2
1  101     Europe      3
2  102         US      1
3  103     Africa      5
4  100     Russia      5
5  101  Australia      7
6  102         US      8
7  104       Asia     10
8  105     Europe     11
9  110     Africa     23

我想把这个数据集的观察值按照 IDRegion分组,然后把每组的 count相加。所以我用了这样的东西。

>>> print(df.groupby(['ID','Region'],as_index=False).count().sum())


ID     Region  count
0  100       Asia      2
1  100     Russia      5
2  101  Australia      7
3  101     Europe      3
4  102         US      9
5  103     Africa      5
6  104       Asia     10
7  105     Europe     11
8  110     Africa     23

在使用 as_index=False时,我能够得到“ SQL 样”输出。我的问题是我无法在这里 重命名聚合变量 count。因此,在 SQL 中,如果想要做上面的事情,我会这样做:

select ID, Region, sum(count) as Total_Numbers
from df
group by ID, Region
order by ID, Region

正如我们所看到的,在 SQL 中从 重命名聚合变量 countTotal_Numbers对我来说是非常容易的。我想做同样的事情在熊猫,但无法找到这样一个选项的功能组。有人能帮忙吗?

第二个问题(更多的是观察)是否..。

Q2)有没有可能在熊猫数据框函数中直接使用列名而不用引号?

我知道变量名是字符串,所以必须在引号中,但是我看到如果在数据框架函数之外使用它们,并且作为一个属性,我们不要求它们在引号中。比如 df.ID.sum()等等。只有当我们在像 df.sort()df.groupby这样的 DataFrame 函数中使用它时,我们才必须在引号中使用它。这实际上有点痛苦,因为在 SQL 或 SAS 或其他语言中,我们只使用变量名而不引用它们。有什么建议吗?

请回答这两个问题(Q1是主要的,Q2更多的是一个意见)。

244074 次浏览

对于第一个问题,我认为答案是:

<your DataFrame>.rename(columns={'count':'Total_Numbers'})

或者

<your DataFrame>.columns = ['ID', 'Region', 'Total_Numbers']

至于第二个问题,我认为答案是否定的。由于 Python 数据模型的原因,可以像“ df.ID”一样使用它:

属性引用转换为此字典中的查找, 例如,m.x 等价于 m.迪克特[“ x”]

在 groupby 操作之后更改列名的当前(从版本0.20开始)方法是链接 rename方法。有关更多细节,请参见文档中的 这张弃用票据

不推荐的答案为熊猫版本0.20

这是在谷歌的第一个结果,虽然顶部的答案工程,它并没有真正回答这个问题。有一个 最好在这里回答和一个很长的 关于 github 的讨论,它们介绍了将字典传递给 agg方法的完整功能。

遗憾的是,这些答案在文档中不存在,但是分组、聚合和重命名列的通用格式使用字典。外部字典的键是要聚合的列名。内部字典有新列命名的键,其值作为聚合函数。

在此之前,让我们创建一个四列 DataFrame。

df = pd.DataFrame({'A' : list('wwwwxxxx'),
'B':list('yyzzyyzz'),
'C':np.random.rand(8),
'D':np.random.rand(8)})


A  B         C         D
0  w  y  0.643784  0.828486
1  w  y  0.308682  0.994078
2  w  z  0.518000  0.725663
3  w  z  0.486656  0.259547
4  x  y  0.089913  0.238452
5  x  y  0.688177  0.753107
6  x  z  0.955035  0.462677
7  x  z  0.892066  0.368850

假设我们想按列 A, B进行分组,用 meanmedian聚合列 C,用 max聚合列 D。下面的代码将执行此操作。

df.groupby(['A', 'B']).agg({'C':['mean', 'median'], 'D':'max'})


D         C
max      mean    median
A B
w y  0.994078  0.476233  0.476233
z  0.725663  0.502328  0.502328
x y  0.753107  0.389045  0.389045
z  0.462677  0.923551  0.923551

这将返回具有层次索引的 DataFrame。最初的问题询问如何在同一步骤中重命名列。使用字典可以做到这一点:

df.groupby(['A', 'B']).agg({'C':{'C_mean': 'mean', 'C_median': 'median'},
'D':{'D_max': 'max'}})


D         C
D_max    C_mean  C_median
A B
w y  0.994078  0.476233  0.476233
z  0.725663  0.502328  0.502328
x y  0.753107  0.389045  0.389045
z  0.462677  0.923551  0.923551

这样可以一次性重命名所有列,但仍然保留了层次索引,可以用 df.columns = df.columns.droplevel(0)删除顶级索引。