Python 按元素对数组进行有效分组
假设我有Python 按元素对数组进行有效分组,python,performance,python-3.x,sorting,numpy,Python,Performance,Python 3.x,Sorting,Numpy,假设我有 lags = [0, 30, 60, 90, 120, 150, 180, np.inf] 及 我希望获得列表中的每个元素,并根据其值将其存储在不同的单独数组中,以便: for all list.values where angles.value is less than 30 list1 = [200, 220, 100] for all list.values where angles.value is between 30 and 60 list2 = [500, 450, 3
lags = [0, 30, 60, 90, 120, 150, 180, np.inf]
及
我希望获得列表中的每个元素,并根据其值将其存储在不同的单独数组中,以便:
for all list.values where angles.value is less than 30
list1 = [200, 220, 100]
for all list.values where angles.value is between 30 and 60
list2 = [500, 450, 350, 450, 340]
for all list.values where angles.value is between 60 and 90
list3 = [800, 670, 830, 850, 630]
等等
我是这样做的:
sortlist = defaultdict(list)
ulist = np.unique(list)
uangle = np.unique(angle)
for lag in lags:
count += 1
for k, dummy_val in enumerate(uangle):
if lag <= uangle[k] < lag + 1:
sortlist[count].append(ulist[k])
sortlist=defaultdict(列表)
ulist=np.unique(列表)
uangle=np.唯一(角度)
对于滞后中的滞后:
计数+=1
对于k,枚举中的伪值(uangle):
如果使用numpy滞后:
angle这是一种矢量化方法-
an = angle.ravel()
sidx = an.argsort()
cut_idx = np.searchsorted(an[sidx], lags)
out = np.split(list1.ravel()[sidx], cut_idx[1:-1])
样本输入、输出-
In [97]: lags = np.array([0, 30, 60, 90, 120, 150, 180, np.inf])
...:
...: list1 = np.array([[500, 800, 1000, 200, 1500], \
...: [220, 450, 350, 1070, 1780], \
...: [900, 450, 1780, 1450, 100],
...: [340, 670, 830, 1370, 1420], \
...: [850, 630, 1230, 1670, 910]])
...:
...: angle = np.array([[50, 80, 100, 20, 150],\
...: [22, 45, 35, 107, 178],\
...: [90, 45, 178, 145, 10],
...: [34, 67, 83, 137, 142],\
...: [85, 63, 123, 167, 91]])
...:
In [99]: out
Out[99]:
[array([100, 200, 220]), # <----- 0 to 30
array([340, 350, 450, 450, 500]), # <----- 30 to 60
array([630, 670, 800, 830, 850]), # <----- 60 to 90
array([ 900, 910, 1000, 1070]), # <----- 90 to 120
array([1230, 1370, 1420, 1450]), # <----- 120 to 150
array([1500, 1670, 1780, 1780]), # <----- 150 to 180
array([], dtype=int64)] # <----- 180 to Inf
[97]中的lags=np.array([0,30,60,90,120,150,180,np.inf])
...:
…:list1=np.array([50080010002001500]\
...: [220, 450, 350, 1070, 1780], \
...: [900, 450, 1780, 1450, 100],
...: [340, 670, 830, 1370, 1420], \
...: [850, 630, 1230, 1670, 910]])
...:
…:角度=np.数组([50,80,100,20,150]\
...: [22, 45, 35, 107, 178],\
...: [90, 45, 178, 145, 10],
...: [34, 67, 83, 137, 142],\
...: [85, 63, 123, 167, 91]])
...:
In[99]:out
出[99]:
[array([100200220]),#解决方案,基于在普通Python中实现它(不含numpy)
您可以将值存储在dict
中,而不是存储在单独的变量中(使用是更好的选择)
您可以创建一个函数,根据角度返回组:
def get_group_from_angle(angle):
group = ''
if angle < 30:
group = 'a'
elif 30 < angle < 60:
group = 'b'
elif 60 < angle < 90:
group = 'c'
return group
my_dict
保存的最终值为:
{
'a': [200, 220, 100],
'b': [500, 450, 350, 450, 340],
'c': [800, 670, 830, 850, 630],
'': [1000, 1500, 1070, 1780, 900, 1780, 1450, 1370, 1420, 1230, 1670, 910]
# ^ number whose angle is not present in any specified range
}
您关心每个输出列表中元素的顺序吗?@Divakar:我不关心顺序。@Divakar,只是删除了它。如果需要,我必须添加“=”。@user7436576更新了滞后中的所有值。为什么剪切_idx[1:-1]
?@MYGz Wellnp.split
只需要间隔重叠的中间索引就可以拆分为数组。因此,我们不需要起始索引和结束索引。
[200, 220, 100]
[500, 450, 350, 450, 340]
[800, 670, 830, 850, 630]
[1000, 1070, 900, 910]
[1450, 1370, 1420, 1230]
[1500, 1780, 1780, 1670]
[]
an = angle.ravel()
sidx = an.argsort()
cut_idx = np.searchsorted(an[sidx], lags)
out = np.split(list1.ravel()[sidx], cut_idx[1:-1])
In [97]: lags = np.array([0, 30, 60, 90, 120, 150, 180, np.inf])
...:
...: list1 = np.array([[500, 800, 1000, 200, 1500], \
...: [220, 450, 350, 1070, 1780], \
...: [900, 450, 1780, 1450, 100],
...: [340, 670, 830, 1370, 1420], \
...: [850, 630, 1230, 1670, 910]])
...:
...: angle = np.array([[50, 80, 100, 20, 150],\
...: [22, 45, 35, 107, 178],\
...: [90, 45, 178, 145, 10],
...: [34, 67, 83, 137, 142],\
...: [85, 63, 123, 167, 91]])
...:
In [99]: out
Out[99]:
[array([100, 200, 220]), # <----- 0 to 30
array([340, 350, 450, 450, 500]), # <----- 30 to 60
array([630, 670, 800, 830, 850]), # <----- 60 to 90
array([ 900, 910, 1000, 1070]), # <----- 90 to 120
array([1230, 1370, 1420, 1450]), # <----- 120 to 150
array([1500, 1670, 1780, 1780]), # <----- 150 to 180
array([], dtype=int64)] # <----- 180 to Inf
def get_group_from_angle(angle):
group = ''
if angle < 30:
group = 'a'
elif 30 < angle < 60:
group = 'b'
elif 60 < angle < 90:
group = 'c'
return group
from collections import defaultdict
my_dict = defaultdict(list)
# `alist` and `angle` are variables holding values as mentioned in Question
for ll, aa in zip(list, angle):
for l, a in zip(ll, aa):
my_dict[get_group_from_angle(a)].append(l)
{
'a': [200, 220, 100],
'b': [500, 450, 350, 450, 340],
'c': [800, 670, 830, 850, 630],
'': [1000, 1500, 1070, 1780, 900, 1780, 1450, 1370, 1420, 1230, 1670, 910]
# ^ number whose angle is not present in any specified range
}