如何编码比例变异的等式(这个paper的等式1)?
我的代码是:
import pandas as pd
l = pd.Series([1,2,3,4,5,6]) # any list of numbers
n = len(l)
if n > 1:
C = (n*(n-1))/2
D = []
for i in l.index:
for j in l.index:
if i != j:
zi_zj = [l[i],l[j]]
D.append(1-((min(zi_zj))/(max(zi_zj))))
PV = (1/C)*(np.sum(D))
else:
PV = 0
如果我列出所有数字相同的列表,我会按预期得到PV = 0
,但是,如果我放入一个带有算术序列的列表,例如[0,2,4,6,8]
,PV = 1.4
,根据文件,PV
应在0
和1
之间,算术序列应为PV = 0.5
与样本量n
无关。
我尝试的另一个选择是:
l = pd.Series([1,2,3,4,5,6]) # any list of numbers
n = len(l)
if n > 1:
C = (n*(n-1))/2
i_s = set()
j_s = set()
D = []
for i in l.index:
for j in l.index:
if i != j:
if i not in i_s:
if j not in j_s:
zi_zj = [l[i],l[j]]
D.append(1-((min(zi_zj))/(max(zi_zj))))
i_s.add(i)
j_s.add(j)
PV = (1/C)*(np.sum(D))
else:
PV = 0
但也没有工作。
另外,我没有在Python中找到一个函数来计算一系列数字的比例变异性。
有人能在代码中发现我做错了什么,或者让我知道是否有内置函数?
答案 0 :(得分:1)
根据我所做的计算,值0.5
仅适用于大n
;请检查我是否犯了错误(没有详细检查论文)。
import pandas as pd
from itertools import combinations
l = pd.Series(list(range(3)))
n = len(l)
C = n * (n - 1) / 2.
# get all pairs in l
pairs = list(combinations(l, 2))
所以对然后看起来如下:
[(0, 1), (0, 2), (1, 2)]
我们现在可以将它存储在数据帧中,因为您已经使用了pandas,这使得后续计算非常简单:
# store pairs in dataframe
df_pairs = pd.DataFrame(pairs).rename(columns={0: 'zi', 1: 'zj'})
# get max / min for each pair
max_val = df_pairs.max(axis=1)
min_val = df_pairs.min(axis=1)
df_pairs['max_z'] = max_val
df_pairs['min_z'] = min_val
# absolute difference between z
df_pairs['diff_z_abs'] = (df_pairs['zi'] - df_pairs['zj']).abs()
df_pairs['ratio_diff_max'] = df_pairs['diff_z_abs'] / df_pairs['max_z']
df_pairs['one_minus_ratio'] = 1. - df_pairs['min_z'] / df_pairs['max_z']
到目前为止,数据框看起来像这样:
zi zj max_z min_z diff_z_abs ratio_diff_max one_minus_ratio
0 0 1 1 0 1 1.0 1.0
1 0 2 2 0 2 1.0 1.0
2 1 2 2 1 1 0.5 0.5
值PV
就是:
PV = df_pairs['ratio_diff_max'].sum() / C
对于此示例,它是0.83333333
,远高于0.5
。但是,如果我们现在改变
l = pd.Series(list(range(3)))
更大的值,PV
然后接近0.5
。例如,对于
l = pd.Series(list(range(5000)))
我获得了
0.500199
所以它可能只适用于n
无限。