열의 값에 따라 다른 함수를 사용하여 조건부로 그룹화 된 데이터 프레임을 집계합니다.

온 파스타

다음 Pandas 데이터 프레임을 고려하십시오.

import pandas as pd

df = pd.DataFrame({"val":[1, 2, 3, 10, 20, 30, 40],
                   "group_id":["ones", "ones", "ones", "tens", "tens", "tens", "tens"],
                   "condition":["sum", "sum", "sum", "mean", "mean", "mean", "mean"]})

df["val"]그룹화 한 group_id다음 각 그룹에 다른 집계 함수를 적용 하여 데이터를 집계하고 싶습니다 . 사용할 집계 함수를 결정하기 위해에서 다른 열을 참조하는 조건 df, 즉 condition.

특히, 나는 모든 요소의 합이 걸릴 싶습니다 val에 대한 "ones"그룹과의 모든 요소의 평균 "tens"그룹. (하지만에서 집계 함수의 이름을 가져올 필요는 없습니다 condition. condition모든 그룹이 동일한 조건 (예 : 모두에 "ones"해당 )이 "sum"있는 한 condition열은 무엇이든 될 수 있습니다 . 따라서 열이 중복 될 수 있습니까?)

다음 결과를 얻고 싶습니다.

df_aggregated = pd.DataFrame({"group_id":["ones", "tens"],
                              "val_aggregated":["6", "25"]})

R 및 dplyr로이를 수행하는 깨끗한 방법이 있습니다.

df <- tibble(val = c(1, 2, 3, 10, 20, 30, 40),
             group_id = c("ones", "ones", "ones", "tens", "tens", "tens", "tens"),
             condition = c("sum", "sum", "sum", "mean", "mean", "mean", "mean"))

df_aggregated <- df %>%
  group_by(group_id) %>% 
  summarise(val_aggregated = case_when(condition == "sum" ~ sum(val),
                                       condition == "mean" ~ mean(val),
                                       TRUE ~ NA_real_)) %>% 
  distinct()

그러나 나는 Pandas에서 이런 종류의 집계를 수행하는 좋은 방법을 찾지 못하는 것 같습니다. 솔루션에 NumPy의 select()기능 이 포함될 수 있습니까? 아니면 Pandas-idiomatic 방법은 그룹화 된 데이터 구조를 반복하는 것입니까?

도움을 주셔서 대단히 감사합니다!

새미 웨미

이를 달성하는 한 가지 방법은 group_idcondition및 집계 에 대해 그룹화하는 것입니다 .

(
    df.groupby(["group_id", "condition"])
    .agg(["sum", "mean"])
    .stack()
    .reset_index() 
     # keeps only rows where condition equals aggregates
    .query("condition==level_2")
    .drop(columns=["condition", "level_2"])
    .rename(columns={"val": "val_aggregated"})
)

    group_id    val_aggregated
0      ones         6
3      tens         25

또 다른 방법은 데이터를 피벗 한 다음 집계하는 것입니다.

result = df.pivot(columns=["group_id", "condition"], values="val")
result

group_id    ones    tens
condition   sum     mean
0           1.0     NaN
1           2.0     NaN
2           3.0     NaN
3           NaN     10.0
4           NaN     20.0
5           NaN     30.0
6           NaN     40.0

onesand teensto sumand 의 페어링을 가져옵니다 mean.

mapping = zip(*result.columns)
mapping = dict(zip(*mapping))
mapping
{'ones': 'sum', 'tens': 'mean'}

condition에서 레벨을 삭제 하고 집계하십시오.

(
    result.droplevel(level="condition", axis="columns")
    .agg(mapping)
    .rename_axis(index="group_id")
    .reset_index(name="val_aggregated")
)


    group_id    val_aggregated
0       ones    6.0
1       tens    25.0

dplyr의 솔루션과 약간 유사한 또 다른 옵션은 np.where질문에서 언급 했듯이을 사용 하는 것입니다.

group = df.groupby("group_id")

(
    df.assign(
        val_aggregate=np.where(
            df.condition.eq("sum"),
            group.val.transform("sum"),
            group.val.transform("mean"),
        )
    )
    .loc[:, ["group_id", "val_aggregate"]]
    .drop_duplicates()
)

    group_id    val_aggregate
0       ones        6
3       tens        25

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관