Python 相当于 Excel 的 PERCENTILE.EXC
Python equivalent of Excel's PERCENTILE.EXC
我正在使用 Pandas 计算一些财务风险分析,包括风险价值。简而言之,要计算风险价值 (VaR),您需要一系列时间序列的模拟投资组合价值变化,然后计算特定的尾部百分位数损失。例如,95% VaR 是该时间序列中的第 5 个百分位数。
我的时间序列在 Pandas 数据框中,目前正在使用 pd.quantile() 函数来计算百分位数。 I ] PERECENTILE.EXC() 有效。 Pandas quantile() 的工作方式类似于 Excel 的 PERCENTILE.INC() 的工作方式 - 它包括指定的百分位数。我已经搜索了几个 python 数学包以及这个论坛的 python 解决方案,它使用与 Excel 中的 PERCENTILE.EXC() 相同的方法,但没有成功。我希望这里有人可以提出建议?
这是示例代码。
import pandas as pd
import numpy as np
test_pd = pd.Series([15,14,18,-2,6,-78,31,21,98,-54,-2,-36,5,2,46,-72,3,-2,7,9,34])
test_np = np.array([15,14,18,-2,6,-78,31,21,98,-54,-2,-36,5,2,46,-72,3,-2,7,9,34])
print 'pandas: ' + str(test_pd.quantile(.05))
print 'numpy: '+ str(np.percentile(test_np,5))
我要找的答案是-77.4
谢谢,
瑞安
编辑:我刚刚看到您的编辑。我认为你犯了一个错误。值 -77.4 实际上是数据的 99.5% 百分位数。尝试 test_pd.quantile(.005)
。我相信您在指定百分位数时一定 Excel 有误。
编辑 2:我刚刚在 Excel 中自己测试了它。对于第 50 个百分位数,我在 Excel 和 Numpy/Pandas 中都得到了正确的值。然而,对于第 5 个百分位数,我在 Pandas/Numpy 中得到 -72,在 Excel 中得到 -74.6。但是 Excel 在这里是错误的:很明显 -74.6 是第 0.5 个百分位,而不是第 5 个...
最终编辑:经过一些测试,Excel 似乎在使用 PERCENTILE.EXC()
函数时围绕非常小的 k 值表现不稳定。事实上,使用任何 k < 0.05 returns 的函数都是错误的,因此 0.05 必须是一个阈值,低于该阈值函数将无法正常工作。我不知道为什么 Excel 在被要求排除第 5 个百分位时选择 return 第 0.5 个百分位(逻辑行为是 return 第 4.9 个百分位,或第 4.99 个。 ..).但是,对于 Numpy,Pandas 和 Excel return 其他 k 值的值相同。例如,PERCENTILE.EXC(0.5) = 6
,还有 test_pd.quantile(0.5) = 6
。我想教训是我们需要警惕 Excel 的行为 ;).
我对你的问题的理解是:你想知道对应于数据的第 k 个百分位数的值,这个第 k 个百分位数被排除在外。但是,pd.quantile()
returns 对应于您的第 k 个百分位的值,包括第 k 个百分位。
我认为 pd.quantile() return 包含第 k 个百分位数不是问题。事实上,假设您希望所有股票的风险价值都严格高于第 5 个百分位数,您会这样做:
mask = data["VaR"] < pd.quantile(data["VaR"], 0.05)
data_filt = data[mask]
因为您使用了 "smaller than" ( < ) 运算符,将排除与您的第 5 个百分位数完全对应的值,类似于 Excel 的 PERCENTILE.EXC()函数。
请告诉我这是否是您要找的。
它不会像 Pandas' 自己的百分位数那样有效,但它应该有效:
def quantile_exc(ser, q):
ser_sorted = ser.sort_values()
rank = q * (len(ser) + 1) - 1
assert rank > 0, 'quantile is too small'
rank_l = int(rank)
return ser_sorted.iat[rank_l] + (ser_sorted.iat[rank_l + 1] -
ser_sorted.iat[rank_l]) * (rank - rank_l)
ser = pd.Series([15,14,18,-2,6,-78,31,21,98,-54,-2,-36,5,2,46,-72,3,-2,7,9,34])
quantile_exc(ser, 0.05)
Out: -77.400000000000006
quantile_exc(ser, 0.1)
Out: -68.399999999999991
quantile_exc(ser, 0.3)
Out: -2.0
请注意 Excel 对于较小的百分位数失败;这不是错误。这是因为低于最小值的等级不适合插值。因此,您可能需要检查 quantile_exc
函数中的等级是否 > 0(请参阅断言部分)。
我正在使用 Pandas 计算一些财务风险分析,包括风险价值。简而言之,要计算风险价值 (VaR),您需要一系列时间序列的模拟投资组合价值变化,然后计算特定的尾部百分位数损失。例如,95% VaR 是该时间序列中的第 5 个百分位数。
我的时间序列在 Pandas 数据框中,目前正在使用 pd.quantile() 函数来计算百分位数。 I ] PERECENTILE.EXC() 有效。 Pandas quantile() 的工作方式类似于 Excel 的 PERCENTILE.INC() 的工作方式 - 它包括指定的百分位数。我已经搜索了几个 python 数学包以及这个论坛的 python 解决方案,它使用与 Excel 中的 PERCENTILE.EXC() 相同的方法,但没有成功。我希望这里有人可以提出建议?
这是示例代码。
import pandas as pd
import numpy as np
test_pd = pd.Series([15,14,18,-2,6,-78,31,21,98,-54,-2,-36,5,2,46,-72,3,-2,7,9,34])
test_np = np.array([15,14,18,-2,6,-78,31,21,98,-54,-2,-36,5,2,46,-72,3,-2,7,9,34])
print 'pandas: ' + str(test_pd.quantile(.05))
print 'numpy: '+ str(np.percentile(test_np,5))
我要找的答案是-77.4
谢谢,
瑞安
编辑:我刚刚看到您的编辑。我认为你犯了一个错误。值 -77.4 实际上是数据的 99.5% 百分位数。尝试 test_pd.quantile(.005)
。我相信您在指定百分位数时一定 Excel 有误。
编辑 2:我刚刚在 Excel 中自己测试了它。对于第 50 个百分位数,我在 Excel 和 Numpy/Pandas 中都得到了正确的值。然而,对于第 5 个百分位数,我在 Pandas/Numpy 中得到 -72,在 Excel 中得到 -74.6。但是 Excel 在这里是错误的:很明显 -74.6 是第 0.5 个百分位,而不是第 5 个...
最终编辑:经过一些测试,Excel 似乎在使用 PERCENTILE.EXC()
函数时围绕非常小的 k 值表现不稳定。事实上,使用任何 k < 0.05 returns 的函数都是错误的,因此 0.05 必须是一个阈值,低于该阈值函数将无法正常工作。我不知道为什么 Excel 在被要求排除第 5 个百分位时选择 return 第 0.5 个百分位(逻辑行为是 return 第 4.9 个百分位,或第 4.99 个。 ..).但是,对于 Numpy,Pandas 和 Excel return 其他 k 值的值相同。例如,PERCENTILE.EXC(0.5) = 6
,还有 test_pd.quantile(0.5) = 6
。我想教训是我们需要警惕 Excel 的行为 ;).
我对你的问题的理解是:你想知道对应于数据的第 k 个百分位数的值,这个第 k 个百分位数被排除在外。但是,pd.quantile()
returns 对应于您的第 k 个百分位的值,包括第 k 个百分位。
我认为 pd.quantile() return 包含第 k 个百分位数不是问题。事实上,假设您希望所有股票的风险价值都严格高于第 5 个百分位数,您会这样做:
mask = data["VaR"] < pd.quantile(data["VaR"], 0.05)
data_filt = data[mask]
因为您使用了 "smaller than" ( < ) 运算符,将排除与您的第 5 个百分位数完全对应的值,类似于 Excel 的 PERCENTILE.EXC()函数。
请告诉我这是否是您要找的。
它不会像 Pandas' 自己的百分位数那样有效,但它应该有效:
def quantile_exc(ser, q):
ser_sorted = ser.sort_values()
rank = q * (len(ser) + 1) - 1
assert rank > 0, 'quantile is too small'
rank_l = int(rank)
return ser_sorted.iat[rank_l] + (ser_sorted.iat[rank_l + 1] -
ser_sorted.iat[rank_l]) * (rank - rank_l)
ser = pd.Series([15,14,18,-2,6,-78,31,21,98,-54,-2,-36,5,2,46,-72,3,-2,7,9,34])
quantile_exc(ser, 0.05)
Out: -77.400000000000006
quantile_exc(ser, 0.1)
Out: -68.399999999999991
quantile_exc(ser, 0.3)
Out: -2.0
请注意 Excel 对于较小的百分位数失败;这不是错误。这是因为低于最小值的等级不适合插值。因此,您可能需要检查 quantile_exc
函数中的等级是否 > 0(请参阅断言部分)。