python 中的分箱可变长度列表
Binning variable length lists in python
我有一个字典 d
有 100 个键,其中的值是可变长度列表,例如
In[165]: d.values()[0]
Out[165]:
[0.0432,
0.0336,
0.0345,
0.044,
0.0394,
0.0555]
In[166]: d.values()[1]
Out[166]:
[0.0236,
0.0333,
0.0571]
我想做的是:对于 d.values()
中的每个列表,我想将值组织到 10 个容器中(如果满足条件,值就会被扔进容器中,例如介于 0.03 和 0.04、0.04 和 0.05 之间,等等)。
我希望最终得到的是看起来与 d
完全一样的东西,但我希望它不是 d.values()[0]
作为数字列表,而是一个列表列表,如下所示:
In[167]: d.values()[0]
Out[167]:
[[0.0336,0.0345,0.0394],
[0.0432,0.044],
[0.0555]]
每个键仍然与相同的值相关联,但它们将被组织到 10 个容器中。
我一直对嵌套 for 循环和 if/elses 等着迷。解决这个问题的最佳方法是什么?
编辑:大家好。只是想让你知道我解决了我的问题。我使用了@Brent Washburne 答案的变体。感谢您的帮助!
您可以通过传递适当的键函数来使用 itertools.groupby()
函数来对您的项目进行分类。在这种情况下,您可以使用 floor(x*100)
作为您的关键函数:
>>> from math import floor
>>> from itertools import groupby
>>> lst = [0.0432, 0.0336, 0.0345, 0.044, 0.0394, 0.0555]
>>> [list(g) for _,g in groupby(sorted(lst), key=lambda x: floor(x*100))]
[[0.0336, 0.0345, 0.0394], [0.0432, 0.044], [0.0555]]
为了将此应用于您的价值观,您可以使用字典理解:
def categorizer(val):
return [list(g) for _,g in groupby(sorted(lst), key=lambda x: floor(x*100))]
new_dict = {k:categorizer(v) for k,v in old_dict.items()}
作为另一种在执行速度方面更优化的方法,您可以使用字典进行分类:
>>> def categorizer(val, d={}):
... for i in val:
... d.setdefault(floor(i*100),[]).append(i)
... return d.values()
为什么不将值设为一组字典,其中 ke 是 bin 指示符,而 values 是该 bin 中那些项目的列表?
yoe 会定义
newd = [{bin1:[], bin2:[], ...binn:[]}, ... ]
newd[0][bin1] = (list of items in d[0] that belong in bin1)
您现在有一个词典列表,每个词典都有相应的 bin 列表。
newd[0]
现在等同于从 d[0]
构建的字典,每个键(我称之为 bin1、bin2、... binn)包含适合该值的列表垃圾桶。因此我们有`newd[0][bin1], newd[0][bin2, ... new[k][lastbin]
字典创建允许您在进行过程中创建适当的键和值列表。如果还没有特定的 bin 键,则创建空列表,然后将值追加到列表中将成功。
现在,当您想要识别一个 bin 的元素时,您可以遍历 newd 列表并提取您想要的任何一个 bin。这允许您拥有没有条目的箱子,而不必创建空列表。如果 bin 键不在 newd 中,则检索设置为 return 默认为空列表(以避免字典无效键异常)。
def bin(values):
bins = [[] for _ in range(10)] # create ten bins
for n in values:
b = int(n * 100) # normalize the value to the bin number
bins[b].append(n) # add the number to the bin
return bins
d = [0.0432,
0.0336,
0.0345,
0.044,
0.0394,
0.0555]
print bin(d)
结果是:
[[], [], [], [0.0336, 0.0345, 0.0394], [0.0432, 0.044], [0.0555], [], [], [], []]
我有一个字典 d
有 100 个键,其中的值是可变长度列表,例如
In[165]: d.values()[0]
Out[165]:
[0.0432,
0.0336,
0.0345,
0.044,
0.0394,
0.0555]
In[166]: d.values()[1]
Out[166]:
[0.0236,
0.0333,
0.0571]
我想做的是:对于 d.values()
中的每个列表,我想将值组织到 10 个容器中(如果满足条件,值就会被扔进容器中,例如介于 0.03 和 0.04、0.04 和 0.05 之间,等等)。
我希望最终得到的是看起来与 d
完全一样的东西,但我希望它不是 d.values()[0]
作为数字列表,而是一个列表列表,如下所示:
In[167]: d.values()[0]
Out[167]:
[[0.0336,0.0345,0.0394],
[0.0432,0.044],
[0.0555]]
每个键仍然与相同的值相关联,但它们将被组织到 10 个容器中。
我一直对嵌套 for 循环和 if/elses 等着迷。解决这个问题的最佳方法是什么?
编辑:大家好。只是想让你知道我解决了我的问题。我使用了@Brent Washburne 答案的变体。感谢您的帮助!
您可以通过传递适当的键函数来使用 itertools.groupby()
函数来对您的项目进行分类。在这种情况下,您可以使用 floor(x*100)
作为您的关键函数:
>>> from math import floor
>>> from itertools import groupby
>>> lst = [0.0432, 0.0336, 0.0345, 0.044, 0.0394, 0.0555]
>>> [list(g) for _,g in groupby(sorted(lst), key=lambda x: floor(x*100))]
[[0.0336, 0.0345, 0.0394], [0.0432, 0.044], [0.0555]]
为了将此应用于您的价值观,您可以使用字典理解:
def categorizer(val):
return [list(g) for _,g in groupby(sorted(lst), key=lambda x: floor(x*100))]
new_dict = {k:categorizer(v) for k,v in old_dict.items()}
作为另一种在执行速度方面更优化的方法,您可以使用字典进行分类:
>>> def categorizer(val, d={}):
... for i in val:
... d.setdefault(floor(i*100),[]).append(i)
... return d.values()
为什么不将值设为一组字典,其中 ke 是 bin 指示符,而 values 是该 bin 中那些项目的列表?
yoe 会定义
newd = [{bin1:[], bin2:[], ...binn:[]}, ... ]
newd[0][bin1] = (list of items in d[0] that belong in bin1)
您现在有一个词典列表,每个词典都有相应的 bin 列表。
newd[0]
现在等同于从 d[0]
构建的字典,每个键(我称之为 bin1、bin2、... binn)包含适合该值的列表垃圾桶。因此我们有`newd[0][bin1], newd[0][bin2, ... new[k][lastbin]
字典创建允许您在进行过程中创建适当的键和值列表。如果还没有特定的 bin 键,则创建空列表,然后将值追加到列表中将成功。
现在,当您想要识别一个 bin 的元素时,您可以遍历 newd 列表并提取您想要的任何一个 bin。这允许您拥有没有条目的箱子,而不必创建空列表。如果 bin 键不在 newd 中,则检索设置为 return 默认为空列表(以避免字典无效键异常)。
def bin(values):
bins = [[] for _ in range(10)] # create ten bins
for n in values:
b = int(n * 100) # normalize the value to the bin number
bins[b].append(n) # add the number to the bin
return bins
d = [0.0432,
0.0336,
0.0345,
0.044,
0.0394,
0.0555]
print bin(d)
结果是:
[[], [], [], [0.0336, 0.0345, 0.0394], [0.0432, 0.044], [0.0555], [], [], [], []]