繁体   English   中英

重用 agg 列 panda group by

[英]resuse agg columns panda group by

我在 csv 文件中有以下内容:

key1    key2    Key3    key4    key5

Val1    A        51     'True'  25
Val1    A        50     'False' 25
Val1    A        49     'True'  25
Val1    A        48     'True'  25
Val2    A        47     'False' 25
Val2    A        46     'True'  25
Val2    A        45     'False' 25
Val2    A        44     'True'  25
Val2    A        43     'True'  25

输出应该是这样的:

key1 key2 max_key5 total_key4 total_true_key4 grade
Val1  A   51       4          3                1
Val2  A   47       5          3                2

我必须按 key1 和 key2 分组,然后找到 key5 的最大值和 key4 的总行数和 key4 的总真实行数,然后是百分比。

我正在尝试什么:

  grd = "1 if avg > 70 else 2 if avg > 50 else c"

    pct = lambda x: (1 if x > 70 else (2 if x > 50 else 3))



json_data
    .assign(_key4=lambda df_: df_['key4'] == "'True'")
    .groupby(['key1', 'key2'])
    .agg(
        maxkey5=('key5', 'max'), 
        total_key4=('key4', 'count'), 
        total_true_key4=('_key4', 'sum')
    )
   .eval('avg = (total_true_key4 * 100) / total_key4')
   .eval('feg = grd')
  #.apply(pct(avg))

用于计算百分比的 eval 工作正常。如果在 avg 列上,则无法执行其他操作

我不想像在另一个单独的声明中那样单独申请。

正如评论中提到的,我不太确定您将如何使用您的逻辑获得所需的输出。 此外,您定义maxkey5=('key5', 'max')但实际上您得到了key3max 所以,如果我没记错的话,你正在寻找这样的东西:

import pandas as pd
from numpy import mean

df = pd.DataFrame({
    "key1": ["Val1"]*4+["Val2"]*5,
    "key2": ["A"]*9,
    "key3": [51, 50, 49, 48, 47, 46, 45, 44, 43],
    "key4": ["'True'", "'False'", "'True'", "'True'", "'False'", "'True'", "'False'", "'True'", "'True'"],
    "key5": [25] * 9
})


(
    df
    .assign(total_true_key4=df['key4']=="'True'", grade=df['key4']=="'True'")
    .groupby(["key1", "key2"])[["key3", "key4", "total_true_key4", "grade"]]
    .agg(
        {"key3": "max", 
         "key4": "count",
         "total_true_key4": "sum",
         "grade": lambda x: 1 if mean(x)>.7 else (2 if mean(x)>.5 else 3)}
    )
    .rename(columns={"key3":"max_key5", "key4":"total_key4"}).reset_index()
)

这导致以下数据框:

   key1   key2  max_key5  total_key4  total_true_key4  grade
0  Val1   A     51        4           3                1
1  Val2   A     47        5           3                2

编辑

IIUC,您想使用您的逻辑并在定义您的avg列后直接分配您的成绩列。 实现这一点的方法如下:

bins = [0, 50, 70, 100]
labels = [3, 2, 1]

(
    df
    .assign(_key4=lambda df_: df_['key4'] == "'True'")
    .groupby(['key1', 'key2'])
    .agg(
        maxkey5=('key5', 'max'), 
        total_key4=('key4', 'count'), 
        total_true_key4=('_key4', 'sum')
    )
   .eval('avg = (total_true_key4 * 100) / total_key4')
   .assign(grade=lambda x: pd.cut(x.avg, bins, labels=labels))
)

输出:

               maxkey5  total_key4  total_true_key4  avg    grade
key1    key2                    
Val1    A      25        4           3               75.0   1
Val2    A      25        5           3               60.0   2

除了最后一个assign语句之外,我没有更改您的逻辑中的任何内容,在该语句中,我使用您评估的avg列和预定义标签和箱的pd.cut方法分配了一个名为grade的新变量。

这个怎么样?

json_data
    .assign(_key4=lambda df_: df_['key4'] == "'True'")
    .groupby(['key1', 'key2'])
    .agg(
        maxkey5=('key5', 'max'), 
        total_key4=('key4', 'count'), 
        total_true_key4=('_key4', 'sum')
        percentage=('key4', lambda x: int(sum(x)/len(x)*100))
    )

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM