【问题标题】:After finding max value, Find succeeding min value in separate column找到最大值后,在单独的列中查找后续最小值
【发布时间】:2019-11-22 06:51:18
【问题描述】:

在我的数据框中,我有这些列。

日期 时间-(5 分钟桶 7:00、7:05、7:10 等....) 高的 低

我想做的是在“高”列中找到最大值,然后在“低”列中找到最小值。

取那个差异,本质上是高-低,然后将它传递给一个新的列

“如果 'High'.max 位于 7:20 行,而最低位在 7:50 行,有什么区别,并将该差异放在 7:20 旁边的行”

在所有这一切结束时,我想得到“时间”所有“高”-“低”差异的平均值或中位数

例如(来自大型数据框)

           Date   Time   Ticker     High      Low    Range
0      01/02/18   7:05  USD/JPY  112.170  112.150
1      01/02/18   7:10  USD/JPY  112.175  112.140
2      01/02/18   7:15  USD/JPY  112.185  112.170
3      01/02/18   7:20  USD/JPY  112.180  112.155   112.180-112.080 = .10
4      01/02/18   7:25  USD/JPY  112.160  112.145
5      01/02/18   7:30  USD/JPY  112.160  112.155
6      01/02/18   7:35  USD/JPY  112.160  112.120
7      01/02/18   7:40  USD/JPY  112.145  112.100
8      01/02/18   7:45  USD/JPY  112.120  112.085
9      01/02/18   7:50  USD/JPY  112.155  112.080
10     01/02/18   7:55  USD/JPY  112.150  112.130
32898  07/05/19  11:35  USD/JPY  108.545  108.525
32899  07/05/19  11:40  USD/JPY  108.550  108.535
32900  07/05/19  11:45  USD/JPY  108.560  108.530   108.560-108.525 = .035
32901  07/05/19  11:50  USD/JPY  108.550  108.540
32902  07/05/19  11:55  USD/JPY  108.535  108.525
32903  07/05/19  12:00  USD/JPY  108.550  108.530
32904  07/05/19  12:05  USD/JPY  108.555  108.530
32905  07/05/19  12:10  USD/JPY  108.560  108.540
32906  07/05/19  12:15  USD/JPY  108.560  108.540

期望的输出

Time    Range (median or avg for all of the instances where the Max High was 7:20 ect)
7:20    .10
11:45   .035

我是否使用 lamdba 来确保我只在找到每天的 High.max 后才找到 Low.min?

我知道我可以按“日期”分组并找到每个日期的最大值。

#High grouped by Date
df2 = df.loc[df.groupby('Date')['High'].idxmax()]

我可以找到范围,但需要找到 High.max 之后的范围,然后找到每个日期的 Low.min,然后按时间。

#Difference between High and Low
range = (df['High']-df['Low'])

但我不知道如何在找到最大值并将差异返回到最大时间发生的位置后找到最小值

【问题讨论】:

  • *如果 high.max 位于 8.05... 则将其放在第 8:00 行的旁边` 在您的示例中看起来不是这样:max 位于 7:15 但您选择了7:20 的值并将结果放在7:20
  • 啊抱歉我会修复它,在我举个例子之前写了它

标签: python pandas dataframe lambda


【解决方案1】:

要获得 最大值之后的最小值,您可以过滤 groupby 组中的行:

df.groupby('Date').apply(lambda x: x.High.max() - x[x.index > x.High.idxmax()].Low.min())

结果:

Date
01/02/18    0.105
07/05/19    0.035

为了验证这是否正常工作,您必须设置例如第一行的最低点至 112.000,即使当天的绝对最小值出现在最大值之前。


如果您也需要时间信息,请将其转换为数据框并插入时间列:

res = df.groupby('Date').apply(lambda x: x.High.max() - x[x.index > x.High.idxmax()].Low.min()).to_frame('Range')
res.insert(0,'Time',df.loc[df.groupby('Date')['High'].idxmax(),'Time'].values)

最终结果:

           Time  Range
Date                  
01/02/18   7:15  0.105
07/05/19  11:45  0.035


更新
如果您希望将范围作为新列插入原始数据框中:

df.loc[df.groupby('Date')['High'].idxmax().values,'Range']=df.groupby('Date').apply(lambda x: x.High.max() - x[x.index > x.High.idxmax()].Low.min()).values

输出:

           Date   Time   Ticker     High      Low  Range
0      01/02/18   7:05  USD/JPY  112.170  112.000    NaN
1      01/02/18   7:10  USD/JPY  112.175  112.140    NaN
2      01/02/18   7:15  USD/JPY  112.185  112.170  0.105
3      01/02/18   7:20  USD/JPY  112.180  112.155    NaN
4      01/02/18   7:25  USD/JPY  112.160  112.145    NaN
5      01/02/18   7:30  USD/JPY  112.160  112.155    NaN
6      01/02/18   7:35  USD/JPY  112.160  112.120    NaN
7      01/02/18   7:40  USD/JPY  112.145  112.100    NaN
8      01/02/18   7:45  USD/JPY  112.120  112.085    NaN
9      01/02/18   7:50  USD/JPY  112.155  112.080    NaN
10     01/02/18   7:55  USD/JPY  112.150  112.130    NaN
32898  07/05/19  11:35  USD/JPY  108.545  108.525    NaN
32899  07/05/19  11:40  USD/JPY  108.550  108.535    NaN
32900  07/05/19  11:45  USD/JPY  108.560  108.530  0.035
32901  07/05/19  11:50  USD/JPY  108.550  108.540    NaN
32902  07/05/19  11:55  USD/JPY  108.535  108.525    NaN
32903  07/05/19  12:00  USD/JPY  108.550  108.530    NaN
32904  07/05/19  12:05  USD/JPY  108.555  108.530    NaN
32905  07/05/19  12:10  USD/JPY  108.560  108.540    NaN
32906  07/05/19  12:15  USD/JPY  108.560  108.540    NaN

【讨论】:

  • 当我运行你的代码时,它似乎没有改变任何 df?当我打印(df)时,它只打印原始数据帧等......您显示的输出对我来说看起来很有希望。关于如何完成这项工作的任何建议?
  • @blankslatecoder 不,它会分别创建一个新的 Series(上部)或 DataFrame(下部)。正如您在问题中所写的所需输出一样。请参阅我在原始数据框中插入值的更新答案。
  • 好的,谢谢,我对此很陌生。下半部分确实给了我和你一样的输出。我现在要努力实现与此类似的输出。时间范围 日期 01/02/18 7:15 0.105 07/05/19 11:45 0.035
  • python df2 = df.groupby('Time', as_index=False)['Range'].mean() 我最终这样做了,因为我是 python 新手,所以我只能弄清楚
  • @blankslatecoder 不客气。如果这解决了您的问题,请考虑accepting the answer。谢谢。
【解决方案2】:

就像我已经评论过的那样,第一个最大值出现在 7:15,而不是 7:20。无论如何,这是我的方法:

new_df = df.groupby('Date').agg({'High': 'idxmax', 'Low':'min'})

# copy the time
new_df['Time'] = df.loc[new_df.High, 'Time'].values

# compute the range
new_df['Range'] = df.loc[new_df.High, 'High'].values - new_df.Low

new_df.drop(['High','Low'], axis=1)

给予:

           Time  Range
Date                  
01/02/18   7:15  0.105
07/05/19  11:45  0.035

【讨论】:

  • 是的,你是对的,这是我的错误。您的代码可以找到该天数范围,但是我正在寻找在“高”最大值之后出现的“低”“最小值”。
猜你喜欢
  • 2018-06-19
  • 2015-10-25
  • 2015-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-11
  • 2015-04-22
相关资源
最近更新 更多