【问题标题】:Create a new pandas DataFrame Column with a groupby使用 groupby 创建一个新的 pandas DataFrame Column
【发布时间】:2021-11-06 07:41:42
【问题描述】:

我有一个数据框,我想按列值分组,然后进行计算以创建一个新列。以下是设置数据:

import pandas as pd

df = pd.DataFrame({
    'Red' : [1,2,3,4,5,6,7,8,9,10],
    'Groups':['A','B','A','A','B','C','B','C','B','C'],
    'Blue':[10,20,30,40,50,60,70,80,90,100]
})
   
df.groupby('Groups').apply(print)

我想做的是在原始数据框中创建一个“TOTAL”列。如果它是组 'TOTAL' 的第一条记录,则得到零,否则 TOTAL 将在索引处得到 ['Blue'] 减去索引处的 ['Red']。

我尝试在下面的函数中执行此操作,但它不起作用。

def funct(group):
    count = 0
    lst = []
    for info in group:
        if count == 0:
            lst.append(0)
            count += 1
        else: 
            num = group.iloc[count]['Blue'] - group.iloc[count-1]['Red']
            lst.append(num)
            count += 1
    group['Total'] = lst
    return group

df = df.join(df.groupby('Groups').apply(funct))

代码适用于第一组,但随后出错。

期望的结果是:

df_final = pd.DataFrame({
    'Red' : [1,2,3,4,5,6,7,8,9,10],
    'Groups':['A','B','A','A','B','C','B','C','B','C'],
    'Blue':[10,20,30,40,50,60,70,80,90,100],
    'Total':[0,0,29,37,48,0,65,74,83,92]
})

df_final

df_final.groupby('Groups').apply(print)

感谢您的帮助!

【问题讨论】:

    标签: pandas dataframe iteration pandas-groupby vectorization


    【解决方案1】:

    对于每个组,计算Blue 和移位Red 之间的差异(上一个索引处的红色):

    df['Total'] = (df.groupby('Groups')
                     .apply(lambda g: g.Blue - g.Red.shift().fillna(g.Blue))
                     .reset_index(level=0, drop=True))
    
    df
    
       Red Groups  Blue  Total
    0    1      A    10    0.0
    1    2      B    20    0.0
    2    3      A    30   29.0
    3    4      A    40   37.0
    4    5      B    50   48.0
    5    6      C    60    0.0
    6    7      B    70   65.0
    7    8      C    80   74.0
    8    9      B    90   83.0
    9   10      C   100   92.0
    

    或者正如@anky 评论的那样,您可以通过首先移动Red 列来避免apply

    df['Total'] = (df.Blue - df.Red.groupby(df.Groups).shift()).fillna(0, downcast='infer')
    
    df
       Red Groups  Blue  Total
    0    1      A    10      0
    1    2      B    20      0
    2    3      A    30     29
    3    4      A    40     37
    4    5      B    50     48
    5    6      C    60      0
    6    7      B    70     65
    7    8      C    80     74
    8    9      B    90     83
    9   10      C   100     92
    

    【讨论】:

    • 谢谢大家,我将深入研究您的答案!
    • 不幸的是,由于泛化,我无法使用它来解决我的问题。显然,这意味着我写的问题很糟糕,因为答案有效。
    • 基本上我想在两个groupby colmun中输入一个复杂的函数,然后更新列,然后用新列恢复原始数据框。
    • 使用 lambda 的问题是我无法获得两个单独的行来执行函数。
    • 不幸的是,我提出的问题是两个简单的问题,并且留下了一个减法工作。
    猜你喜欢
    • 2023-01-10
    • 2021-06-05
    • 2016-05-14
    • 1970-01-01
    • 2019-02-17
    • 2022-12-15
    • 1970-01-01
    • 2021-04-15
    • 2019-11-04
    相关资源
    最近更新 更多