【问题标题】:Pandas Dataframes remove duplicate index, keep largest value first depending on column valuePandas Dataframes 删除重复索引,根据列值首先保留最大值
【发布时间】:2022-01-22 12:43:59
【问题描述】:

这是我当前的 df。我想分 3 步转换数据框。我需要删除重复的时间戳,但希望根据“边”列保留最大值或最小值。请帮忙:)

我已经尝试过df= df[~df.index.duplicated(keep='first')],但这没有保留最大值或最小值的选项

索引类型为datetime格式,Price为float,Side为整数,数据框8000+行。

                          Price      Side  
2021-12-13 00:00:03.285   51700      4     
2021-12-13 00:00:03.315   51675      3    
2021-12-13 00:00:03.333   50123      4    
2021-12-13 00:00:03.333   50200      3    
2021-12-13 00:00:03.333   50225      3   
2021-12-13 00:00:03.333   50250      3    
2021-12-13 00:00:03.421   50123      4     
2021-12-13 00:00:03.421   50117      4     
2021-12-13 00:00:03.421   50110      4    
2021-12-13 00:00:03.671   50100      3     
  1. 如果时间重复,边为“3”时保持最大值,如果时间重复边为“4”时保持最小值。
Desired Output:
                          Price      Side  
2021-12-13 00:00:03.285   51700      4     
2021-12-13 00:00:03.315   51675      3    
2021-12-13 00:00:03.333   50123      4 
2021-12-13 00:00:03.333   50250      3     
2021-12-13 00:00:03.421   50110      4     
2021-12-13 00:00:03.671   50100      3     
  1. 创建具有相应价格的新列“3”和“4”
Desired Output:
                          Price      3         4  
2021-12-13 00:00:03.285   51700      0         51700
2021-12-13 00:00:03.315   51675      51675     0  
2021-12-13 00:00:03.333   50123      0         50123
2021-12-13 00:00:03.333   50250      50250     0     
2021-12-13 00:00:03.421   50110      0         50110  
2021-12-13 00:00:03.671   50100      50100     0  
  1. 用同一列以前的值填空
Desired Output:
                          Price      3         4  
2021-12-13 00:00:03.285   51700      0         51700  
2021-12-13 00:00:03.315   51675      51675     51700  
2021-12-13 00:00:03.333   50123      51675     50123
2021-12-13 00:00:03.333   50250      50250     50123     
2021-12-13 00:00:03.421   50110      50250     50110  
2021-12-13 00:00:03.671   50100      50100     50110          

【问题讨论】:

  • “如果边是 3”是什么意思?组2021-12-13 00:00:03.333有四个项目,三个边是3,一个是4。你如何确定那个时候的边?
  • 哦等等,你想按time分组 side

标签: pandas dataframe jupyter-notebook time-series trading


【解决方案1】:
new_df = (df
    .groupby([pd.Grouper(level=0), 'Side'])
    .apply(lambda x: x['Price'].max() if x['Side'].mode()[0] == 3 else x['Price'].min())
    .reset_index()
)
new_df = (
    pd.concat([
        new_df,
        (new_df
            .pivot(columns='Side', values=0)
            .ffill()
            .fillna(0)
        )
    ], axis=1)
    .drop('Side', axis=1)
    .rename({0: 'Price'}, axis=1)
)

输出:

>>> df
                    index  Price        3        4
0 2021-12-13 00:00:03.285  51700      0.0  51700.0
1 2021-12-13 00:00:03.315  51675  51675.0  51700.0
2 2021-12-13 00:00:03.333  50250  50250.0  51700.0
3 2021-12-13 00:00:03.333  50123  50250.0  50123.0
4 2021-12-13 00:00:03.421  50110  50250.0  50110.0
5 2021-12-13 00:00:03.671  50100  50100.0  50110.0

精简版:

new_df = df.groupby([pd.Grouper(level=0), 'Side']).apply(lambda x: x['Price'].max() if x['Side'].mode()[0] == 3 else x['Price'].min()).reset_index()
new_df = pd.concat([new_df, new_df.pivot(columns='Side', values=0).ffill().fillna(0)], axis=1).drop('Side', axis=1).rename({0:'Price'}, axis=1))

【讨论】:

  • 不需要reset_index,可以groupby(level = 0, 'Side')
  • @sammywemmy 我之前尝试过,但没有成功。它只是忽略by='Side' 并仅按level=0 分组。
  • 我的错:df.groupby([pd.Grouper(level=0), 'Side'])
  • 甜蜜!虽然,它实际上只短了 2 个字符......:P
  • 大声笑,我提到了,因为避免索引重置可能更有效,因为 groupby 会生成索引。如果你已经有一个索引,它的计算效率应该更高......但你永远不知道......
【解决方案2】:

这是一个选项,有点长:

(df.assign(temp = df.Side.map({4:'low', 3:'high'}))
.groupby([pd.Grouper(level=0), 'Side', 'temp'], sort = False)
.Price
.agg(['min', 'max'])
.unstack('Side')
.loc(axis=1)[[('max', 3), ('min', 4)]]
.droplevel(level = 0,axis = 1)
.droplevel(level = 'temp')
.assign(Price=lambda df: df[3].where(df[3].notna(), df[4]))
.ffill()
.fillna(0)
.astype(int)
.rename_axis(columns = None)
)

                             3      4  Price
2021-12-13 00:00:03.285      0  51700  51700
2021-12-13 00:00:03.315  51675  51700  51675
2021-12-13 00:00:03.333  51675  50123  50123
2021-12-13 00:00:03.333  50250  50123  50250
2021-12-13 00:00:03.421  50250  50110  50110
2021-12-13 00:00:03.671  50100  50110  50100

这假定Side 中的唯一值是 3 和 4。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-29
    • 2019-10-10
    • 1970-01-01
    • 2021-10-25
    • 1970-01-01
    • 1970-01-01
    • 2019-04-06
    • 2018-05-27
    相关资源
    最近更新 更多