149

Pandas の groupby 機能に問題があります。ドキュメントを読みましたが、集計関数を複数の列適用し、それらの列にカスタム名を付ける方法がわかりません。

これは非常に近いですが、返されたデータ構造にはネストされた列見出しがあります。

data.groupby("Country").agg(
        {"column1": {"foo": sum()}, "column2": {"mean": np.mean, "std": np.std}})

(つまり、列 2 の平均値と標準値を取得したいが、それらの列を「平均値」と「標準値」として返します)

私は何が欠けていますか?

4

6 に答える 6

138

これにより、階層列インデックスから最も外側のレベルが削除されます。

df = data.groupby(...).agg(...)
df.columns = df.columns.droplevel(0)

最も外側のレベルを保持したい場合は、複数レベルの列で ravel() 関数を使用して新しいラベルを作成できます。

df.columns = ["_".join(x) for x in df.columns.ravel()]

例えば:

import pandas as pd
import pandas.rpy.common as com
import numpy as np

data = com.load_data('Loblolly')
print(data.head())
#     height  age Seed
# 1     4.51    3  301
# 15   10.89    5  301
# 29   28.72   10  301
# 43   41.74   15  301
# 57   52.70   20  301

df = data.groupby('Seed').agg(
    {'age':['sum'],
     'height':['mean', 'std']})
print(df.head())
#       age     height           
#       sum        std       mean
# Seed                           
# 301    78  22.638417  33.246667
# 303    78  23.499706  34.106667
# 305    78  23.927090  35.115000
# 307    78  22.222266  31.328333
# 309    78  23.132574  33.781667

df.columns = df.columns.droplevel(0)
print(df.head())

収量

      sum        std       mean
Seed                           
301    78  22.638417  33.246667
303    78  23.499706  34.106667
305    78  23.927090  35.115000
307    78  22.222266  31.328333
309    78  23.132574  33.781667

または、インデックスの最初のレベルを保持するには:

df = data.groupby('Seed').agg(
    {'age':['sum'],
     'height':['mean', 'std']})
df.columns = ["_".join(x) for x in df.columns.ravel()]

収量

      age_sum   height_std  height_mean
Seed                           
301        78    22.638417    33.246667
303        78    23.499706    34.106667
305        78    23.927090    35.115000
307        78    22.222266    31.328333
309        78    23.132574    33.781667
于 2013-09-29T13:47:39.513 に答える
11

同じ場所で出力列に名前を付けて定義する方が自然で一貫しているように見えるというOPに同意します(たとえば、 Rの tidyversesummarizeで行われているように)が、今のところ pandas での回避策は、で新しい列を作成することです集計を行う前に、必要な名前を指定します。assign

data.assign(
    f=data['column1'],
    mean=data['column2'],
    std=data['column2']
).groupby('Country').agg(dict(f=sum, mean=np.mean, std=np.std)).reset_index()

( 、、、およびreset_indexallを使用して、別の整数インデックスを持つ通常の列にします。)'Country''f''mean''std'

于 2018-03-20T21:11:41.860 に答える
1

この種のデータフレームなど、列名には 2 つのレベルがあります。

 shop_id  item_id   date_block_num item_cnt_day       
                                  target              
0   0       30          1            31               

このコードを使用できます:</p>

df.columns = [col[0] if col[-1]=='' else col[-1] for col in df.columns.values]

結果は次のとおりです。

 shop_id  item_id   date_block_num target              
0   0       30          1            31 
于 2019-03-05T10:53:13.127 に答える