Python相当于Excel的百分比.EXC

2024-06-12 05:33:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我用熊猫来计算一些金融风险分析,包括风险价值。简言之,要计算风险价值(VaR),您需要模拟投资组合价值变化的时间序列,然后计算特定的尾部百分位损失。例如,95%VaR是该时间序列中的第5个百分位数字。在

我的时间序列在Pandas数据帧中,目前正在使用分位数()计算百分位数的函数。我的问题是,VaR的典型市场惯例是使用排除百分位(即:95%的VaR被解释为:有95%的机会你的投资组合不会失去超过计算的数字)-类似于MS Excel百分位数()有效。Pandas quantile()的工作原理类似于Excel的百分位公司()有效-它包括指定的百分比。我已经搜索了几个python数学包以及这个论坛,寻找一个使用与百分比.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

谢谢

瑞安


Tags: testimportpandasvarnp时间序列数字
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函数中的rank>;0(参见断言部分)。在

编辑:我刚看到你的编辑。我认为你犯了个错误。值-77.4实际上是数据的99.5%。尝试test_pd.quantile(.005)。我相信你在Excel中指定你的百分位数时一定出错了。在

编辑2:我刚用Excel测试过。对于第50个百分位,我在Excel和Numpy/Pandas中都得到了正确的值。然而,对于第5个百分位,熊猫/纽比的得分是-72,Excel的得分是-74.6。但是Excel在这里是错的:很明显-74.6是0.5%,而不是第5个。。。在

最终编辑:经过一些测试后,Excel似乎在使用PERCENTILE.EXC()函数的非常小的k值时表现异常。实际上,将函数与任何k<;0.05一起使用都会返回一个错误,因此0.05必须是一个阈值,低于该阈值函数将无法正常工作。我不知道为什么Excel在要求排除第5个百分位数时选择返回0.5%(逻辑行为是返回4.9%或4.99%)。但是,Numpy、Pandas和Excel对于其他k值都返回相同的值。例如,PERCENTILE.EXC(0.5) = 6,和{}。我想教训是我们需要警惕Excel的行为;)。在

我理解你的问题的方式是:你想知道你的数据的第k个百分位对应的值,这个k百分位不包括在内。但是,pd.quantile()返回与第k个百分位相对应的值,包括该第k个百分位。在

我不这么认为分位数()返回包含的第k个百分位数是一个问题。事实上,假设您希望所有股票的风险价值严格高于第5个百分点,您可以:

mask = data["VaR"] < pd.quantile(data["VaR"], 0.05)
data_filt = data[mask]

因为您使用了“小于”(<;)运算符,因此将排除与第5个百分位完全对应的值,这与Excel的类似百分比.EXC()功能。在

告诉我这是不是你要找的。在

似乎包org.apache.commons.math3.stat.descriptive.rankPercentile函数的实现与Excel中的PERCENTILE.EXC函数密切相关。在

下面是Python实现和一些小的调整。在

这里rowpandas.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

相关问题 更多 >