我有这样的熊猫DataFrame

n = 6000
my_data = DataFrame ({
    "Category"  : np.random.choice (['cat1','cat2'], size=n) ,
    "val_1"     : np.random.randn(n) ,
    "val_2"     : [i for i in range (1,n+1)]
})


我在Category上进行汇总,并对不同的列应用不同的功能,如下所示:

counts_and_means = \
    my_data.groupby("Category").agg (
        {
            "Category"  : np.count_nonzero ,
            "val_1"     : np.mean ,
            "val_2"     : np.mean
        }
    )


完成此操作后,我需要一个显式的列顺序和新的列名。我使用reindexrename做到这一点,以流畅的样式将它们与原始聚合链接起来,如下所示:

counts_and_means = \
    my_data.groupby("Category").agg (
        {
            "Category"  : np.count_nonzero ,
            "val_1"     : np.mean ,
            "val_2"     : np.mean
        }
    ) \
    .reindex (columns = ["Category","val_1","val_2"]) \
    .rename (
        columns = {
            "Category" : "Count" ,
            "val_1"    : "Avg. Val_1" ,
            "val_2"    : "Avg. Val_2" ,
        }
    )


这是最好的方法吗(就成语,表现等而言)?还是有一种方法可以在agg(...)步骤中显式指定列名和顺序?

我之所以问是因为我不熟悉此API的习惯用法,并且想使其正确使用,并且因为看起来reindexrename都创建了DataFrame副本,这对于大型数据集可能是一个更大的问题(我知道inplacerename参数,但这在我的流利设置中不起作用)。任何帮助/建议,不胜感激。

最佳答案

值得注意的是,在Python 3.3+中,字典的顺序没有被保证(并且每次调用甚至都不相同):

In [11]: counts_and_means = \
    my_data.groupby("Category").agg (
        {
            "Category"  : np.count_nonzero ,
            "val_1"     : np.mean ,
            "val_2"     : np.mean
        }
    )

In [12]: counts_and_means
Out[12]:
                val_2  Category     val_1
Category
cat1      2972.181788      3009  0.005821
cat2      3028.988633      2991  0.027436


解决此问题的一种方法是使用OrderedDict

In [13]: from collections import OrderedDict

In [14]: counts_and_means = \
    my_data.groupby("Category").agg(
        OrderedDict([
            ("Category", np.count_nonzero),
            ("val_1",    np.mean),
            ("val_2",    np.mean)
        ])
    )

In [15]: counts_and_means
Out[15]:
          Category     val_1        val_2
Category
cat1          3009  0.005821  2972.181788
cat2          2991  0.027436  3028.988633


现在,您可以使用.columns属性直接重命名:

In [16]: counts_and_means.columns = ["Count", "Avg_val1", "Avg_val2"]


注意:在列名称中使用.的IMO不可pandaroble,因为您不能再将列作为DataFrame属性访问。尝试并尽可能保留这些标识符。



我想说的另一种选择可能是更惯用*,而不是那么冗长,它是迭代构建的:

In [21]: g = my_data.groupby("Category")

In [22]: counts_and_means = g["Category"].agg(np.count_nonzero).to_frame(name="Count")
         counts_and_means["Avg_val1"] = g["val_1"].agg("mean")
         counts_and_means["Avg_val2"] = g["val_2"].agg("mean")

In [23]: counts_and_means
Out[23]:
          Count  Avg_val1     Avg_val2
Category
cat1       3009  0.005821  2972.181788
cat2       2991  0.027436  3028.988633


*您无需一站式完成所有任务!! :)

关于python - Pandas :重命名,汇总列时最好的习惯用法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29721666/

10-12 17:01