首页 > 解决方案 > 在 Python 中使用 Dataframe 上的 groupby 函数进行条件分组

问题描述

我正在为一个项目编码,但我被困在这里。我以前使用过groupby函数,但不是这样。我的疑问是——

我有一个如下的数据框:

| ID | Side | Price |
| 1  | left | 100   |
| 2  | right| 90    |
| 3  | right| 50    |
| 2  | left | 70    |
| 3  | left | 110   |

我想按 ID 分组,然后减去该 ID 的价格。如果价格为left > right,则 ID 必须设置为 left ,价格应为left_price - right_price,类似地right > left,最终价格为left_price - right_price

上面的输出应该是这样的:

| ID | Side | Price |
| 1  | left | 100   |
| 2  | right| 20    |
| 3  | left | -60   |

我正在使用 python-2.7。这是我到目前为止编写的代码(或正在尝试编写)

id_group = df.sort_values(['ID','Side'])
id_group = df.groupby(['ID'])['Price'].diff().fillna(df['Price'])

标签: pythonpandaspython-2.7group-bypandas-groupby

解决方案


如果您在同一侧有多个 ID,我会在您的示例中引入一个额外的数据点(-参见 id:2),在这种情况下,{price}如果复合键{id, side}相同,它将聚合。请在下面找到我的解决方案。

data = {'ID':[1,2,2,3,2,3], 
    'Side':['left', 'left','right', 'right','left', 'left'],
    'Price':[100,10,90,50,70,110]
    }

df = pd.DataFrame.from_dict(data)
df

   ID   Side    Price
0   1   left    100
1   2   left    10
2   2   right   90
3   3   right   50
4   2   left    70
5   3   left    110

df_pivot = df.pivot_table(
           index='ID', 
           columns='Side', 
           values='Price', 
           aggfunc='sum', 
           fill_value=0)
df_pivot

Side left right
ID      
1   100   0
2   80    90
3   110   50

#**custom function** 
    def evaluate_side(row):
        if row['left'] > row['right']:
            return 'left', row['left']-row['right']
        else: 
            return 'right', row['left']-row['right']

#Results Table Only
result = df_pivot.apply(lambda x: evaluate_side(x), axis=1, result_type='expand')
result.rename(columns={0:'Result', 1:'Price'}, inplace=True)
print(result)

   Result  Price
ID              
1    left    100
2   right    -10
3    left     60

#Full Table with Original Values
df_pivot[result.columns] = result
print(df_pivot)

Side  left  right Result  Price
ID                             
1      100      0   left    100
2       80     90  right    -10
3      110     50   left     60

推荐阅读