pandas python 中基于行的过滤器和聚合

问题描述 投票:0回答:1

我有两个数据框如下

df1:

data1 = {
    'Acc': [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4],
    'indi_val': ['Val1', 'val2', 'Val_E', 'Val1_E', 'Val1', 'Val3', 'val2', 'val2_E', 'val22_E', 'val2_A', 'val2_V', 'Val_E', 'Val_A', 'Val', 'Val2', 'val7'],
    'Amt': [10, 20, 5, 5, 22, 38, 15, 25, 22, 23, 24, 56, 67, 45, 87, 88]
}
df1 = pd.DataFrame(data1)

df2:

data2 = {
    'Acc': [1, 1, 2, 2, 3, 4],
    'Indi': ['With E', 'Without E', 'With E', 'Without E', 'Normal', 'Normal']
}
df2 = pd.DataFrame(data2)

基于这两个数据框,我需要创建最终输出,如下所示:

 AccNo   Indi      Amt
 1      With E      7
 1      Without E   90
 2      With E      47
 2      Without E   62
 3      Normal      225
 4      Normal      88

逻辑:

  • with E
    :来自 df1,其中
    indi_val
    值应为最后两个字符 等于“_E”然后求和(Amt)。
  • Without E
    :来自 df1,其中
    indi_val
    值最后两个字符不应等于“_E”,然后等于 Sum(Amt)。
  • Noraml
    :df1
    indi_val
    列上没有任何过滤器需要对(Amt)值求和

我尝试写如下内容:


def get_indi(row):
    listval = []
    if row['Indi'] == "With E":
        #print('A')
        df1.apply(lambda df1row: listval.append(df1row['amt'] if df1row['Acc']==row['Acc'] and df1row['indi_val'][-2:]=="_E" else 0))
    
    if row['Indi'] == "Without E":
        df1.apply(lambda df1row: listval.append(df1row['amt'] if df1row['Acc']==row['Acc'] and df1row['indi_val'][-2:]!="_E" else 0))
    
    if row['Indi'] == "Normal":
        df1.apply(lambda df1row: listval.append(df1row['amt']))
        
    return sum(listval)

# Apply the function to create the 'Indi' column in df1
df2['Amt'] = df2.apply(get_indi)

使用上面的代码我收到一个错误

获取_loc 引发 KeyError(key) 关键错误:'Indi'

python pandas dataframe
1个回答
0
投票

首先,apply 可能不是最好的方法here,但是对于您的用例,您需要为所有 apply 调用明确提及

axis=1
,如下所示:

df2.apply(get_indi, axis=1)

更好的解决方案是使用 pandas group by 和聚合,然后进行合并操作:

df_temp = []
# normal
qwe = df1.groupby('Acc')['Amt'].sum().reset_index()
qwe['Indi'] = 'Normal'
df_temp.append(qwe)
# With E
qwe = df1[df1['indi_val'].str.endswith('_E')].groupby('Acc')['Amt'].sum().reset_index()
qwe['Indi'] = 'With E'
df_temp.append(qwe)
# Without E
qwe = df1[~df1['indi_val'].str.endswith('_E')].groupby('Acc')['Amt'].sum().reset_index()
qwe['Indi'] = 'Without E'
df_temp.append(qwe)

df_temp = pd.concat(df_temp)
# merge
df2.merge(df_temp, on=['Acc', 'Indi'])

输出:

ACC 印度 阿姆特
0 1 与E 10
1 1 没有E 90
2 2 与E 47
3 2 没有E 62
4 3 正常 255
5 4 正常 88
© www.soinside.com 2019 - 2024. All rights reserved.