programing

반환된 열의 이름을 Pandas Aggregate 함수에 지정하시겠습니까?

minimums 2023. 6. 27. 22:02
반응형

반환된 열의 이름을 Pandas Aggregate 함수에 지정하시겠습니까?

저는 기능적으로 판다 그룹과 문제가 있습니다.설명서를 읽었지만 집계 함수를 여러 에 적용하고 해당 열에 사용자 지정 이름을 지정하는 방법을 알 수 없습니다.

이는 매우 근접하지만 반환되는 데이터 구조에는 중첩된 열 제목이 있습니다.

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

(즉, 2열의 평균과 표준을 취하려고 하지만 이 열들을 "평균"과 "표준"으로 반환합니다.)

제가 무엇을 빠뜨리고 있나요?

판다의 경우 >= 0.

반환된 집계 열의 이름을 지정하는 기능이 마스터 분기에 다시 도입되었으며 판다 0.25를 대상으로 합니다.새로운 구문은 다음과 같습니다..agg(new_col_name=('col_name', 'agg_func')위에 링크된 PR의 자세한 예:

In [2]: df = pd.DataFrame({'kind': ['cat', 'dog', 'cat', 'dog'],
   ...:                    'height': [9.1, 6.0, 9.5, 34.0],
   ...:                    'weight': [7.9, 7.5, 9.9, 198.0]})
   ...:

In [3]: df
Out[3]:
  kind  height  weight
0  cat     9.1     7.9
1  dog     6.0     7.5
2  cat     9.5     9.9
3  dog    34.0   198.0

In [4]: df.groupby('kind').agg(min_height=('height', 'min'), 
                               max_weight=('weight', 'max'))
Out[4]:
      min_height  max_weight
kind
cat          9.1         9.9
dog          6.0       198.0

PR에 따라 이 구문과 앞서(아래) 제안한 2단계 이름 바꾸기 구문을 사용하여 여러 람다 식을 사용할 수도 있습니다.PR의 예에서 다시 복사합니다.

In [2]: df = pd.DataFrame({"A": ['a', 'a'], 'B': [1, 2], 'C': [3, 4]})

In [3]: df.groupby("A").agg({'B': [lambda x: 0, lambda x: 1]})
Out[3]:
         B
  <lambda> <lambda 1>
A
a        0          1

그리고 나서..rename()또는 한 번에:

In [4]: df.groupby("A").agg(b=('B', lambda x: 0), c=('B', lambda x: 1))
Out[4]:
   b  c
A
a  0  0

판다 < 0.25

현재 unutbu 설명에 의해 받아들여진 답변은 판다 버전 <= 0.20에서 이를 수행하는 훌륭한 방법입니다.그러나 판다 0.20부터 이 방법을 사용하면 향후 버전의 판다에서는 구문을 사용할 수 없을 것이라는 경고가 표시됩니다.

시리즈:

미래 경고: 시리즈에서 집계에 딕트를 사용하는 것은 더 이상 권장되지 않으며 향후 버전에서 제거될 예정입니다.

데이터 프레임:

미래 경고: 딕트를 이름 변경과 함께 사용하는 것은 더 이상 권장되지 않으며 이후 버전에서 제거됩니다.

판다 0.20 변경 로그에 따르면 집계하는 동안 열 이름을 변경하는 권장 방법은 다음과 같습니다.

# Create a sample data frame
df = pd.DataFrame({'A': [1, 1, 1, 2, 2],
                   'B': range(5),
                   'C': range(5)})

# ==== SINGLE COLUMN (SERIES) ====
# Syntax soon to be deprecated
df.groupby('A').B.agg({'foo': 'count'})
# Recommended replacement syntax
df.groupby('A').B.agg(['count']).rename(columns={'count': 'foo'})

# ==== MULTI COLUMN ====
# Syntax soon to be deprecated
df.groupby('A').agg({'B': {'foo': 'sum'}, 'C': {'bar': 'min'}})
# Recommended replacement syntax
df.groupby('A').agg({'B': 'sum', 'C': 'min'}).rename(columns={'B': 'foo', 'C': 'bar'})
# As the recommended syntax is more verbose, parentheses can
# be used to introduce line breaks and increase readability
(df.groupby('A')
    .agg({'B': 'sum', 'C': 'min'})
    .rename(columns={'B': 'foo', 'C': 'bar'})
)

자세한 내용은 0.20 변경 로그를 참조하십시오.

@JunkMechanic의 의견에 따라 2017-01-03을 업데이트합니다.

오래된 스타일의 사전 구문을 사용하여 여러 개를 전달하는 것이 가능했습니다.lambda에 대한 기능..agg전달된 사전의 키로 이름이 바뀌었기 때문입니다.

>>> df.groupby('A').agg({'B': {'min': lambda x: x.min(), 'max': lambda x: x.max()}})

    B    
  max min
A        
1   2   0
2   4   3

여러 함수를 하나의 열에 목록으로 전달할 수도 있습니다.

>>> df.groupby('A').agg({'B': [np.min, np.max]})

     B     
  amin amax
A          
1    0    2
2    3    4

반환되므로.<lambda>이름 충돌이 발생합니다.

>>> df.groupby('A').agg({'B': [lambda x: x.min(), lambda x: x.max]})
SpecificationError: Function names must be unique, found multiple named <lambda>

다음을 방지하기 위해SpecificationError명명된 함수는 사용하는 대신 선험적으로 정의될 수 있습니다.lambda적절한 함수 이름도 호출을 피합니다..rename나중에 데이터 프레임에 저장합니다.위와 같은 목록 구문으로 다음 함수를 전달할 수 있습니다.

>>> def my_min(x):
>>>     return x.min()

>>> def my_max(x):
>>>     return x.max()

>>> df.groupby('A').agg({'B': [my_min, my_max]})

       B       
  my_min my_max
A              
1      0      2
2      3      4

계층형 열 인덱스에서 가장 바깥쪽 수준이 삭제됩니다.

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

가장 바깥쪽 레벨을 유지하려면 다중 레벨 열의 레이블() 기능을 사용하여 새 레이블을 구성할 수 있습니다.

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

업데이트: 대신 새로운 팬더에서..ravel()사용하다.tolist()또는.to_numpy() use df.columns = ["_".join(x) for x in df.columns.tolist()]


예:

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

동일한 위치에서 출력 열의 이름을 지정하고 정의하는 것이 더 자연스럽고 일관적이라는 OP에 동의하지만(예: R의 tidyverse에서 수행하는 것처럼), 현재 판다에서 해결책은 집계를 수행하기 전에 를 통해 원하는 이름으로 새 열을 만드는 것입니다.

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()

(회전 사용)'Country','f','mean',그리고.'std'모두 별도의 정수 인덱스를 가진 정규 열로 변환됩니다.)

JMP와 유사한 동작을 수행하려면 다중 인덱스의 모든 정보를 보관하는 열 제목을 작성합니다.

newidx = []
for (n1,n2) in df.columns.ravel():
    newidx.append("%s-%s" % (n1,n2))
df.columns=newidx

데이터 프레임이 다음과 같이 변경됩니다.

    I                       V
    mean        std         first
V
4200.0  25.499536   31.557133   4200.0
4300.0  25.605662   31.678046   4300.0
4400.0  26.679005   32.919996   4400.0
4500.0  26.786458   32.811633   4500.0

로.

    I-mean      I-std       V-first
V
4200.0  25.499536   31.557133   4200.0
4300.0  25.605662   31.678046   4300.0
4400.0  26.679005   32.919996   4400.0
4500.0  26.786458   32.811633   4500.0

@Joel Ostblom의 영감으로.

단순 집계용으로 이미 작업 가능한 사전을 가지고 있는 사용자는 최신 버전 집계에 대해 다음 코드를 사용/수정하여 집계와 부분 이름 변경을 구분할 수 있습니다.항목이 두 개 이상일 경우 중첩된 사전을 숙지하십시오.

def agg_translate_agg_rename(input_agg_dict):
    agg_dict = {}
    rename_dict = {}
    for k, v in input_agg_dict.items():
        if len(v) == 1:
            agg_dict[k] = list(v.values())[0]
            rename_dict[k] = list(v.keys())[0]
        else:
            updated_index = 1
            for nested_dict_k, nested_dict_v in v.items():
                modified_key = k + "_" + str(updated_index)
                agg_dict[modified_key] = nested_dict_v
                rename_dict[modified_key] = nested_dict_k
                updated_index += 1
    return agg_dict, rename_dict

one_dict = {"column1": {"foo": 'sum'}, "column2": {"mean": 'mean', "std": 'std'}}
agg, rename = agg_translator_aa(one_dict)

우리는.

agg = {'column1': 'sum', 'column2_1': 'mean', 'column2_2': 'std'}
rename = {'column1': 'foo', 'column2_1': 'mean', 'column2_2': 'std'}

더 현명한 방법이 있다면 알려주시기 바랍니다.감사해요.

이러한 종류의 데이터 프레임과 같이 열 이름에는 두 가지 수준이 있습니다.

 shop_id  item_id   date_block_num item_cnt_day       
                                  target              
0   0       30          1            31               

다음 코드를 사용할 수 있습니다.

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 

언급URL : https://stackoverflow.com/questions/19078325/naming-returned-columns-in-pandas-aggregate-function

반응형