在 Python 中使用 Dataframe 上的 groupby 函数进行条件分组

Posted

技术标签:

【中文标题】在 Python 中使用 Dataframe 上的 groupby 函数进行条件分组【英文标题】:Conditional groupping in Python using groupby function on Dataframe 【发布时间】:2021-10-07 17:41:29 【问题描述】:

我正在为一个项目编码,但我被困在这里。我以前使用过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'])

【问题讨论】:

(不是投反对票的人)-这个问题可能被投反对票,因为您自己解决这个问题的努力还没有显示出来。请更新问题以表明您尝试自己解决此问题。 另外,由于 Python 我知道,但我无法更新它。它与工作有关。 我解决了你的问题,但我猜你的描述是错误的。你的最终结果应该是 1: ['left', 100], 2: ['right', 20], 3: ['left', 60],而不是 1: ['left', 100], 2:['右',20],3:['左',-60]。因为你是从高点减去低点。 不,价格必须遵循相同的模式。像减法一样应该从一侧到另一侧进行。不像正常情况下从大到小。 【参考方案1】:

功能:

Number_of_Ids=dict(DF["Id"].value_counts())
SideID_price=
def Side_by_max(row):
    for row in DF.values:
        ID=row[0]
        Side=row[1]
        Price=row[2]
        if Number_of_Ids[ID]>1:
            if ID not in SideID_price.keys():
                SideID_price[ID]=[Side,Price]
            else:
                Previous_Side,Previous_Price=SideID_price[ID]
                if Previous_Side==Side:
                    calculated_price=Previous_Price+Price
                else:
                    calculated_price=Previous_Price-Price 
                SideID_price[ID]=[Side,calculated_price]

        else:
            SideID_price[ID]=[Side,Price]

获取字典:

Side_by_max(DF.values)

重构生成的 DF:

Result=pd.DataFrame(SideID_price).T
Result.index.name = "ID"

【讨论】:

【参考方案2】:

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

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

【讨论】:

以上是关于在 Python 中使用 Dataframe 上的 groupby 函数进行条件分组的主要内容,如果未能解决你的问题,请参考以下文章

使用行上的部分字符串匹配返回DataFrame项pandas python [重复]

python 从ArcGIS Online上的要素图层集合中搜索,选择和生成pandas DataFrame。

使用 Pandas DataFrame 样式为列着色(Python 3)

spark 2.3.1 上的 dataframe,Describe() 函数抛出 Py4JJavaError

python dataframe pandas使用int删除列

Python数据分析笔记#8.2.2 索引上的合并