对列表中的条目数进行下采样(不进行插值)
我有一个包含许多条目的 Python 列表,我需要使用以下任一方法对其进行下采样:
- 最大行数。例如,将 1234 个条目的列表限制为 1000。
- 原始行的比例。例如,将列表设为原始长度的 1/3。
(我需要能够同时执行这两种方法,但一次只能使用一种方法)。
我相信,对于最大行数,我只需计算所需的比例并将其传递给比例缩小器:
def downsample_to_max(self, rows, max_rows):
return downsample_to_proportion(rows, max_rows / float(len(rows)))
...所以我实际上只需要一个下采样函数。有什么提示吗?
编辑:该列表包含对象,而不是数值,因此我不需要插值。扔掉物体是没问题的。
解决方案:
def downsample_to_proportion(self, rows, proportion):
counter = 0.0
last_counter = None
results = []
for row in rows:
counter += proportion
if int(counter) != last_counter:
results.append(row)
last_counter = int(counter)
return results
谢谢。
I have a Python list with a number of entries, which I need to downsample using either:
- A maximum number of rows. For example, limiting a list of 1234 entries to 1000.
- A proportion of the original rows. For example, making the list 1/3 its original length.
(I need to be able to do both ways, but only one is used at a time).
I believe that for the maximum number of rows I can just calculate the proportion needed and pass that to the proportional downsizer:
def downsample_to_max(self, rows, max_rows):
return downsample_to_proportion(rows, max_rows / float(len(rows)))
...so I really only need one downsampling function. Any hints, please?
EDIT: The list contains objects, not numeric values so I do not need to interpolate. Dropping objects is fine.
SOLUTION:
def downsample_to_proportion(self, rows, proportion):
counter = 0.0
last_counter = None
results = []
for row in rows:
counter += proportion
if int(counter) != last_counter:
results.append(row)
last_counter = int(counter)
return results
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以使用
itertools
中的islice
:用法:
You can use
islice
fromitertools
:Usage:
如果输入已经是序列类型,则直接使用切片语法比使用
islice()
+list()
更有效:Instead of
islice()
+list()
it is more efficient to use slice syntax directly if the input is already a sequence type:这个解决方案对于原始海报来说可能有点过大,但我想我会分享我一直用来解决这个问题和类似问题的代码。
它有点长(大约 90 行),但如果你经常有这种需求,想要一个易于使用的 oneliner,并且需要一个纯 Python 的无依赖环境,那么我认为它可能会有用。
基本上,您唯一要做的就是将列表传递给函数并告诉它您希望新列表的长度,该函数将:
所有内容都收集在一个函数内,因此如果您需要它,只需将其复制并粘贴到您的脚本中,您就可以立即开始使用它。
例如,您可能会说:
并得到
注意,由于浮点限制,会出现轻微的错误。另外,我是为 Python 2.x 编写的,因此要在 Python 3.x 上使用它,只需添加一行
xrange = range
即可。这是一个在列表列表中的定位子项之间进行插值的巧妙技巧。例如,您可以轻松地在 RGB 颜色元组之间进行插值,以创建 x nr 级的颜色渐变。假设您使用 RGB 颜色元组列表 3 和所需的 GRADIENTLENGTH 变量来执行此操作:
它可能需要相当多的优化,我必须做相当多的实验。如果您觉得可以改进,请随时编辑我的帖子。这是代码:
This solution might be a bit overkill for the original poster, but I thought I would share the code that I've been using to solve this and similar problems.
It's a bit lengthy (about 90 lines), but if you often have this need, want an easy-to-use oneliner, and need a pure-Python dependency free environment then I reckon it might be of use.
Basically, the only thing you have to do is pass your list to the function and tell it what length you want your new list to be, and the function will either:
Everything is collected inside one function so if you need it just copy and paste it to your script and you can start using it right away.
For instance you might say:
and get
Note that minor inaccuracies will occur due to floating point limitations. Also, I wrote this for Python 2.x, so to use it on Python 3.x just add a single line that says
xrange = range
.And here is a nifty trick to interpolate between positioned subitems in a list of lists. So for instance you can easily interpolate between RGB color tuples to create a color gradient of x nr of steps. Assuming a list of RGB color tuples of 3 and a desired GRADIENTLENGTH variable you do this with:
It probably could need quite a few optimizations, I had to do quite a bit of experimentation. If you feel you can improve it feel free to edit my post. Here is the code:
保留一个计数器,并按第二个值递增。每次将其下限,并产生该指数的值。
Keep a counter, which you increment by the second value. Floor it each time, and yield the value at that index.
random.choices() 不能解决您的问题吗?
更多示例请参见此处
Can't random.choices() solve your problem?
More examples are available here
参考 Ignacio Vazquez-Abrams 的回答:
从 7 个可用数字中打印 3 个数字:
输出:
对于将许多日志消息下采样到较小的子集很有用。
With reference to answer from Ignacio Vazquez-Abrams:
Print 3 numbers from the 7 available:
Output:
Useful for down-sampling many log messages to a smaller subset.