【发布时间】:2018-06-16 12:49:27
【问题描述】:
我有多个数组对应于时间序列的数据参数。数据参数包括速度、发生时间、发生日期、发生月份、发生时间等。
我正在尝试从最高到最低的出现频率查找与指定数据参数的分组相对应的索引。
举个简单的例子,考虑以下几点:
import numpy as np
speed = np.array([4, 6, 8, 3, 6, 9, 7, 6, 4, 3])*100
elap_hr = sorted(np.random.randint(low=1, high=40, size=10))
## ... other time parameter arrays
print(speed)
# [400 600 800 300 600 900 700 600 400 300]
print(elap_hr)
# [ 1 2 6 7 13 19 21 28 33 38]
所以观察到speed = 400(2次出现)对应于elapsed hours = 1, 33; speed = 600(出现 3 次)对应于 elapsed hours = 2, 13, 28。
对于这个例子,假设我有兴趣按出现频率对speed 进行分组。一旦有了将speed 从最高频率到最低频率分组的索引,我就可以在其他数据参数数组(如elap_hr)上应用相同的索引。
我先排序和argsortspeed;然后我找到 sorted speed 的独特元素。我将这些组合起来以找到与排序唯一 speed 相对应的排序 speed 的索引,这些索引在排序唯一 speed 中按值分组为子数组。
def get_sorted_data(data, sort_type='default'):
if sort_type == 'default':
res = sorted(data)
elif sort_type == 'argsort':
res = np.argsort(data)
elif sort_type == 'by size':
res = sorted(data, key=len)
return res
def sort_data_by_frequency(data):
uniq_data = np.unique(data)
sorted_data = get_sorted_data(data)
res = [np.where(sorted_data == uniq_data[i])[0] for i in range(len(uniq_data))]
res = get_sorted_data(res, 'by size')[::-1]
return res
sorted_speed = get_sorted_data(speed)
argsorted_speed = get_sorted_data(speed, 'argsort')
freqsorted_speed = sort_data_by_frequency(speed)
print(sorted_speed)
# [300, 300, 400, 400, 600, 600, 600, 700, 800, 900]
print(argsorted_speed)
# [3 9 0 8 1 4 7 6 2 5]
print(freqsorted_speed)
# [array([4, 5, 6]), array([2, 3]), array([0, 1]), array([9]), array([8]), array([7])]
在freqsorted_speed中,第一个子数组[4, 5, 6]对应于排序数组中元素[600, 600, 600]的索引。
到目前为止还可以。但是,我希望索引适用于所有数据参数数组。所以,我需要将 argsorted 索引映射到原始数组索引。
def get_dictionary_mapping(keys, values):
## since all indices are unique, there is no worry about identical keys
return dict(zip(keys, values))
idx_orig = np.array([i for i in range(len(argsorted_speed))], dtype=int)
index_to_index_map = get_dictionary_mapping(idx_orig, argsorted_speed)
print(index_to_index_map)
# {0: 3, 1: 9, 2: 0, 3: 8, 4: 1, 5: 4, 6: 7, 7: 6, 8: 2, 9: 5}
print(speed[idx_orig])
# [400 600 800 300 600 900 700 600 400 300]
print(speed[argsorted_speed])
# [300 300 400 400 600 600 600 700 800 900]
print([index_to_index_map[idx_orig[i]] for i in range(len(idx_orig))])
# [3, 9, 0, 8, 1, 4, 7, 6, 2, 5]
我拥有完成我想要的所有必要的部分。但我不太确定如何把它放在一起。任何建议将不胜感激。
编辑:
作为最终结果,我希望将 speed 的原始索引按频率分组,如下所示:
res = [[1, 4, 7], [3, 9], [0, 8], ...]
## corresponds to 3 600's, 2 300's, 2 400's, etc.
## for values of equal frequency, the secondary grouping is from min-to-max
这样,我可以按第 n 个最频繁的值或频率本身来选择值。
【问题讨论】:
-
您能否更具体地说明您想要的最终结果是什么?
-
我刚刚添加了一个编辑部分来澄清。
标签: python-3.x sorting numpy indexing frequency