【问题标题】:Conditional groupping in Python using groupby function on Dataframe在 Python 中使用 Dataframe 上的 groupby 函数进行条件分组
【发布时间】: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]}。因为你是从高点减去低点。
  • 不,价格必须遵循相同的模式。像减法一样应该从一侧到另一侧进行。不像正常情况下从大到小。

标签: python pandas python-2.7 group-by pandas-groupby


【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2020-10-20
      • 1970-01-01
      • 2018-01-26
      • 1970-01-01
      • 2013-07-30
      • 2016-08-28
      • 2021-04-06
      • 1970-01-01
      • 2017-05-03
      相关资源
      最近更新 更多