Python 输出与元组列表的中值关联的记录,由 numpy 确定
Python to output record associated with median value of a tuple list, determined by numpy
我正在使用 numpy
从这样的元组列表中查找中值:
print(np.median( [x[1] for x in pairs]) )
Pairs
本身来自 collections.namedtuple,它们单独看起来像这样:
Pair(hash=u'0x034c9e7f28f136188ebb2a2630c26183b3df90c387490159b411cf7326764341', gas=21000)
Pair(hash=u'0xffda7269775dcd710565c5e0289a2254c195e006f34cafc80c4a3c89f479606e', gas=1000000)
Pair(hash=u'0x90ca439b7daa648fafee829d145adefa1dc17c064f43db77f573da873b641f19', gas=90000)
Pair(hash=u'0x7cba9f140ab0b3ec360e0a55c06f75b51c83b2e97662736523c26259a730007f', gas=40000)
Pair(hash=u'0x92dedff7dab405220c473aefd12e2e41d260d2dff7816c26005f78d92254aba2', gas=21000)
这是我确定中位数的方法:
pairs = list(_as_pairs(dict_hash_gas))
# pprint.pprint(pairs)
if pairs:
# Avoid a ValueError from min() and max() if the list is empty.
print(min(pairs, key=lambda pair: pair.gas))
print(max(pairs, key=lambda pair: pair.gas))
print(np.median( [x[1] for x in pairs]) )
结构的创建方式如下:
def _as_pairs(pairs):
for pair in pairs:
# TODO: Verify the dict conatains exactly one item?
for k, v in pair.items():
# Should the `key` string also be an integer?
#yield Pair(key=int(k, base=16), value=int(v))
yield Pair(hash=k, gas=int(v))
完整脚本可以发声here.
目前输出是这样的:
Pair(hash=u'0xf4f034e23b4118cb4aa4e9d077f0f28d675e25e9dc2650225f32ac33e04c93aa', gas=21000)
Pair(hash=u'0x92de9056a6357752a46dff1d6ff274d204d450bbd6c51cefe757f199af105cb4', gas=4712388)
90000.0
问题是,我如何输出整个记录,整个 Pair
,与中值相关联,而不只是中值本身?
可以得到中位数Pair的索引,但需要多一行:
1) 如果你总是有 len(pairs)%2 == 1
,中位数是唯一的并且属于对:
gases = np.array([pair.gas for pair in pairs])
medianGasIndex = np.where( gases == np.median(gases) )[0][0]
print(pairs[medianGasIndex])
2) 如果你可能有len(pairs)%2 == 0
,那么你要选择:
2.1) 要么你想要中值对,它是真实中值的最接近值(即第 50 个百分位数,不包含在数据集中)
medianGasIndex = np.where( gases == np.percentile(gases,50,interpolation='nearest') )[0][0]
2.2) 或者您想要左右中值
leftMedianGasIndex = np.where( gases == np.percentile(gases,50,interpolation='lower') )[0][0]
rightMedianGasIndex = np.where( gases == np.percentile(gases,50,interpolation='higher') )[0][0]
它与此minimal working example一起使用,只需根据您的需要编辑获取中值的方式即可。
这个问题是不适定的,因为没有真正与中位数相关联的值:median
值可能不存在于原始数组中,例如np.median([0, 1])
等于 0.5
.
相反,您可以使用 np.argmin()
找到最接近中位数的 pairs
的值,例如:
import numpy as np
arr = np.arange(10, 20)
median_val = np.median(arr)
print(median_val)
# output: 14.5
i = np.argmin(np.abs(arr - median_val))
print(i)
# output: 4
print(arr[i])
# output: 14
对于您的代码,这可能类似于:
gases_arr = np.array([pair.gas for pair in pairs])
median_val = np.median(gases_arr)
i = np.argmin(np.abs(gases_arr - median_gases))
print(i, pairs[i])
当然,除非您希望仅当 median
实际存在于数组中时才打印该值,在这种情况下,您可以检查 pairs[i] == median_val
或使用 where
如其他答案所述。
我正在使用 numpy
从这样的元组列表中查找中值:
print(np.median( [x[1] for x in pairs]) )
Pairs
本身来自 collections.namedtuple,它们单独看起来像这样:
Pair(hash=u'0x034c9e7f28f136188ebb2a2630c26183b3df90c387490159b411cf7326764341', gas=21000)
Pair(hash=u'0xffda7269775dcd710565c5e0289a2254c195e006f34cafc80c4a3c89f479606e', gas=1000000)
Pair(hash=u'0x90ca439b7daa648fafee829d145adefa1dc17c064f43db77f573da873b641f19', gas=90000)
Pair(hash=u'0x7cba9f140ab0b3ec360e0a55c06f75b51c83b2e97662736523c26259a730007f', gas=40000)
Pair(hash=u'0x92dedff7dab405220c473aefd12e2e41d260d2dff7816c26005f78d92254aba2', gas=21000)
这是我确定中位数的方法:
pairs = list(_as_pairs(dict_hash_gas))
# pprint.pprint(pairs)
if pairs:
# Avoid a ValueError from min() and max() if the list is empty.
print(min(pairs, key=lambda pair: pair.gas))
print(max(pairs, key=lambda pair: pair.gas))
print(np.median( [x[1] for x in pairs]) )
结构的创建方式如下:
def _as_pairs(pairs):
for pair in pairs:
# TODO: Verify the dict conatains exactly one item?
for k, v in pair.items():
# Should the `key` string also be an integer?
#yield Pair(key=int(k, base=16), value=int(v))
yield Pair(hash=k, gas=int(v))
完整脚本可以发声here.
目前输出是这样的:
Pair(hash=u'0xf4f034e23b4118cb4aa4e9d077f0f28d675e25e9dc2650225f32ac33e04c93aa', gas=21000)
Pair(hash=u'0x92de9056a6357752a46dff1d6ff274d204d450bbd6c51cefe757f199af105cb4', gas=4712388)
90000.0
问题是,我如何输出整个记录,整个 Pair
,与中值相关联,而不只是中值本身?
可以得到中位数Pair的索引,但需要多一行:
1) 如果你总是有 len(pairs)%2 == 1
,中位数是唯一的并且属于对:
gases = np.array([pair.gas for pair in pairs])
medianGasIndex = np.where( gases == np.median(gases) )[0][0]
print(pairs[medianGasIndex])
2) 如果你可能有len(pairs)%2 == 0
,那么你要选择:
2.1) 要么你想要中值对,它是真实中值的最接近值(即第 50 个百分位数,不包含在数据集中)
medianGasIndex = np.where( gases == np.percentile(gases,50,interpolation='nearest') )[0][0]
2.2) 或者您想要左右中值
leftMedianGasIndex = np.where( gases == np.percentile(gases,50,interpolation='lower') )[0][0]
rightMedianGasIndex = np.where( gases == np.percentile(gases,50,interpolation='higher') )[0][0]
它与此minimal working example一起使用,只需根据您的需要编辑获取中值的方式即可。
这个问题是不适定的,因为没有真正与中位数相关联的值:median
值可能不存在于原始数组中,例如np.median([0, 1])
等于 0.5
.
相反,您可以使用 np.argmin()
找到最接近中位数的 pairs
的值,例如:
import numpy as np
arr = np.arange(10, 20)
median_val = np.median(arr)
print(median_val)
# output: 14.5
i = np.argmin(np.abs(arr - median_val))
print(i)
# output: 4
print(arr[i])
# output: 14
对于您的代码,这可能类似于:
gases_arr = np.array([pair.gas for pair in pairs])
median_val = np.median(gases_arr)
i = np.argmin(np.abs(gases_arr - median_gases))
print(i, pairs[i])
当然,除非您希望仅当 median
实际存在于数组中时才打印该值,在这种情况下,您可以检查 pairs[i] == median_val
或使用 where
如其他答案所述。