我正在使用Pandas来计算一些财务风险分析,包括风险价值。简而言之,要计算风险价值(VaR),您需要计算模拟投资组合价值变化的时间序列,然后计算特定的尾部百分位数损失。例如,95%的VaR是该时间序列中的第5百分位数。
我在Pandas数据框中有时间序列,目前正在使用pd.quantile()函数来计算百分位数。我的问题是,VaR的典型市场惯例是使用排他性百分位数(即:95%VaR被解释为:您的投资组合有95%的可能不会超过计算数量) - 类似于MS Excel 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
谢谢,
赖安
答案 0 :(得分:3)
它不会像熊猫自己的百分位那样有效,但它应该有效:
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会因小百分位数而失败;这不是一个bug。这是因为低于最小值的等级不适合插值。所以你可能想检查排名> quantile_exc
函数中的0(参见断言部分)。
答案 1 :(得分:2)
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 test_pd.quantile(0.5) = 6
也是如此。我想教训我们需要警惕Excel的行为;)。
我理解您的问题的方式是:您想知道与您的数据的第k百分位数相对应的值,排除此第k个百分位数。但是,pd.quantile()
会返回与您的第k百分位数对应的值,包括此第k个百分位数。
我不认为pd.quantile()返回包含的第k个百分位是一个问题。实际上,假设您希望所有股票的风险价值严格高于第5个百分点,您可以这样做:
mask = data["VaR"] < pd.quantile(data["VaR"], 0.05)
data_filt = data[mask]
因为您使用了“小于”(&lt;)运算符,所以将排除与您的第5个百分位数完全对应的值,类似于Excel的PERCENTILE.EXC()函数。
请告诉我这是否是你要找的。 p>
答案 2 :(得分:0)
似乎包Percentile
中org.apache.commons.math3.stat.descriptive.rank
函数的实现与Excel中的PERCENTILE.EXC
函数有联系。
下面是带有一些细微调整的Python实现。
row
是pandas.Series
row_sorted = row.sort_values()
n = len(row_sorted)
# index start from 0 so we need to -1
pos = quantile * (n + 1) - 1
# If pos < 0 return the smallest element in the array.
if pos < 0:
var = row_sorted.iat[0]
# Else if pos >= n - 1 return the largest element in the array.
if pos >= n - 1:
var = row_sorted.iat[n - 1]
# floor(pos)
pos_lower = int(pos)
# the fractional part of pos
d = pos - pos_lower
# the next element index
pos_upper = pos_lower + 1
# calculate var
lower = row_sorted.iat[pos_lower]
upper = row_sorted.iat[pos_upper]
var = lower + (upper - lower) * d