感谢您的回答,我之前没有使用过StackOverflow,因此我对答案的数量和速度感到惊讶 - 这太棒了。
我还没有正确理解答案,但我想我应该在问题规范中添加一些信息。见下图。
我无法在此发布图片,因为我没有足够的分数,但您可以看到图像 在http://journal.acquitane.com/2010-01-20/image003.jpg
此图片可能更贴切地描述我想要实现的目标。因此,您可以在整个页面的水平线上看到图表上的价格点。现在,您可以在每个0.5%的范围内获得线条聚类,这被认为是一件好事,为什么我想自动识别这些聚类。您可以在图表上看到S2& MR1,R2& WPP1。
所以我每天都会产生这些价位,然后我可以手动识别0.5%以内的价格。 - 但这个问题的目的是如何使用python例程。
我再次使用标签复制了这个列表(见下文)。请注意,列表价格点与图像中的价格点不匹配,因为它们来自两个不同的日期。
[YR3,175.24,8] [SR3,147.85,6] [YR2,144.13,8] [SR2,130.44,6] [YR1,127.79,8] [QR3,127.42,5] [SR1,120.94,6] [QR2,120.22,5] [MR3,118.10,3] [WR3,116.73,2] [DR3,116.23,1] [WR2,115.93,2] [QR1,115.83,5] [MR2,115.56,3] [DR2,115.53,1] [WR1,114.79,2] [DR1,114.59,1] [WPP,113.99,2] [DPP,113.89,1] [MR1,113.50,3] [DS1,112.95,1] [WS1,112.85,2] [DS2,112.25,1] [WS2,112.05,2] [DS3,111.31,1] [MPP,110.97,3] [WS3,110.91,2] [50MA,110.87,4] [MS1,108.91,3] [QPP,108.64,5] [MS2,106.37,3] [MS3,104.31,3] [QS1,104.25,5] [SPP,103.53,6] [200MA,99.42,7] [QS2,97.05,5] [YPP,96.68,8] [SS1,94.03,6] [QS3,92.66,5] [YS1,80.34,8] [SS2,76.62,6] [SS3,67.12,6] [YS2,49.23,8] [YS3,32.89,8]
我确实在原始列表中犯了一个错误,因为C组错了,不应该包括在内。感谢您指出了这一点。
0.5%也没有固定,这个值每天都会变化,但我只是用0.5%作为规范问题的例子。
再次感谢。 标记
PS。我现在就开始检查答案。
嗨:
我需要对股票价格进行一些操纵。我刚刚开始使用Python,(但我认为在任何语言中实现它都会遇到麻烦)。我正在寻找一些关于如何在python中很好地实现它的想法。
由于 标记
问题: 我有一个列表列表(FloorLevels(见下文)),其中子列表有两个项目(股票价格,权重)。我想将股票价格分成小组,当它们在彼此的0.5%之内时。团体力量将由其总重量决定。例如:
Group-A
115.93,2
115.83,5
115.56,3
115.53,1
-------------
TotalWeight:12
-------------
Group-B
113.50,3
112.95,1
112.85,2
-------------
TotalWeight:6
-------------
FloorLevels[
[175.24,8]
[147.85,6]
[144.13,8]
[130.44,6]
[127.79,8]
[127.42,5]
[120.94,6]
[120.22,5]
[118.10,3]
[116.73,2]
[116.23,1]
[115.93,2]
[115.83,5]
[115.56,3]
[115.53,1]
[114.79,2]
[114.59,1]
[113.99,2]
[113.89,1]
[113.50,3]
[112.95,1]
[112.85,2]
[112.25,1]
[112.05,2]
[111.31,1]
[110.97,3]
[110.91,2]
[110.87,4]
[108.91,3]
[108.64,5]
[106.37,3]
[104.31,3]
[104.25,5]
[103.53,6]
[99.42,7]
[97.05,5]
[96.68,8]
[94.03,6]
[92.66,5]
[80.34,8]
[76.62,6]
[67.12,6]
[49.23,8]
[32.89,8]
]
答案 0 :(得分:3)
我建议重复使用k-means clustering - 让我们简称为KMC。 KMC是一种简单而强大的聚类算法......但它需要“被告知”您要瞄准的聚类数量k
。你事先并不知道(如果我理解你的话) - 你只想要最小的k
,这样两个项目“聚集在一起”就不会超过X%
。所以,从k
等于1
开始 - 所有东西都聚集在一起,不需要聚类传递;-) - 并检查聚类的直径(聚类的“直径”,来自术语的使用在几何中,是群集中任何两个成员之间的最大距离。)
如果直径为> X%
,请设置k += 1
,使用k
作为群集数执行KMC,然后迭代重复检查。
在伪代码中:
def markCluster(items, threshold):
k = 1
clusters = [items]
maxdist = diameter(items)
while maxdist > threshold:
k += 1
clusters = Kmc(items, k)
maxdist = max(diameter(c) for c in clusters)
return clusters
当然我们假设我们有合适的diameter
和Kmc
Python函数。
这听起来像你想要的那种吗?如果是这样,那么我们可以继续向您展示如何编写diameter
和Kmc
(如果您的items
数量相对有限,则使用纯Python进行处理,否则可能会通过利用强大的第三方附加框架,例如numpy
) - 但如果你真的想要一些非常不同的东西,那么就不值得去做这个问题了! - )
答案 1 :(得分:2)
如果s
中的每个股票G
,t
* 1.05> = G
,则股票s
属于某个群组t
和s
/ 1.05< = t
,对吧?
我们如何将股票添加到每个组?如果我们有股票95,100,101和105,我们开始一个100组,然后加101,我们将以{100,101,105}结束。如果我们在100之后做了95,我们最终得到{100,95}。
我们只需要考虑所有可能的排列吗?如果是这样,您的算法效率会很低。
答案 2 :(得分:2)
您需要更详细地指明您的问题。什么“当股票价格在彼此的0.5%之内时将它们分成小组”是什么意思?
的可能性:
(1)该组的每个成员都在该组的每个其他成员的0.5%之内
(2)对列表进行排序并将其拆分到差距大于0.5%
的位置请注意,116.23在115.93 - abs((116.23 / 115.93 - 1) * 100) < 0.5
的0.5%范围内 - 但您在A组中放了一个数字,在C组中放了一个。
简单示例:a, b, c = (0.996, 1, 1.004)
...请注意a和b适合,b和c适合,但a和c不适合。你希望他们如何分组,为什么?输入列表中的顺序是否相关?
可能性(1)产生ab,c或a,bc ......打破平局规则,请
可能性(2)产生abc(没有大的差距,所以只有一组)
答案 3 :(得分:1)
您将无法将其归类为“硬”群组。如果你有价格(1.0,1.05,1.1)那么第一个和第二个应该在同一个组中,第二个和第三个应该在同一个组中,而不是第一个和第三个。
快速,肮脏的方式做一些你可能会觉得有用的事情:
def make_group_function(tolerance = 0.05):
from math import log10, floor
# I forget why this works.
tolerance_factor = -1.0/(-log10(1.0 + tolerance))
# well ... since you might ask
# we want: log(x)*tf - log(x*(1+t))*tf = -1,
# so every 5% change has a different group. The minus is just so groups
# are ascending .. it looks a bit nicer.
#
# tf = -1/(log(x)-log(x*(1+t)))
# tf = -1/(log(x/(x*(1+t))))
# tf = -1/(log(1/(1*(1+t)))) # solved .. but let's just be more clever
# tf = -1/(0-log(1*(1+t)))
# tf = -1/(-log((1+t))
def group_function(value):
# don't just use int - it rounds up below zero, and down above zero
return int(floor(log10(value)*tolerance_factor))
return group_function
用法:
group_function = make_group_function()
import random
groups = {}
for i in range(50):
v = random.random()*500+1000
group = group_function(v)
if group in groups:
groups[group].append(v)
else:
groups[group] = [v]
for group in sorted(groups):
print 'Group',group
for v in sorted(groups[group]):
print v
print
答案 4 :(得分:0)
对于给定的一组股票价格,可能有多种方法可以将彼此相差0.5%的股票分组。如果没有一些额外的价格分组规则,就无法确定答案会做你真正想要的。
答案 5 :(得分:0)
除了选择哪些值组合在一起的正确方法之外,这是一个问题,其中一个小的面向对象落入可以使它更容易处理。
我在这里制作了两个课程,只有最少的理想行为,但是这可以使分类变得更容易 - 你可以在Group课程中单独使用它。
我可以看到下面的代码是不正确的,在某种意义上,随着新成员的添加,组包含的限制会有所不同 - 即使它与分离crieteria重新相同,你仍然可以使用get_groups方法来使用多遍做法。它应该很难 - 但代码太长了,无法在这里提供帮助,而且我认为这个剪辑是让你顺利进行的:
from copy import copy
class Group(object):
def __init__(self,data=None, name=""):
if data:
self.data = data
else:
self.data = []
self.name = name
def get_mean_stock(self):
return sum(item[0] for item in self.data) / len(self.data)
def fits(self, item):
if 0.995 < abs(item[0]) / self.get_mean_stock() < 1.005:
return True
return False
def get_weight(self):
return sum(item[1] for item in self.data)
def __repr__(self):
return "Group-%s\n%s\n---\nTotalWeight: %d\n\n" % (
self.name,
"\n".join("%.02f, %d" % tuple(item) for item in self.data ),
self.get_weight())
class StockGrouper(object):
def __init__(self, data=None):
if data:
self.floor_levels = data
else:
self.floor_levels = []
def get_groups(self):
groups = []
floor_levels = copy(self.floor_levels)
name_ord = ord("A") - 1
while floor_levels:
seed = floor_levels.pop(0)
name_ord += 1
group = Group([seed], chr(name_ord))
groups.append(group)
to_remove = []
for i, item in enumerate(floor_levels):
if group.fits(item):
group.data.append(item)
to_remove.append(i)
for i in reversed(to_remove):
floor_levels.pop(i)
return groups
测试:
floor_levels = [ [stock. weight] ,... <paste the data above> ]
s = StockGrouper(floor_levels)
s.get_groups()
答案 6 :(得分:0)
对于分组元素,你能使用itertools.groupby()吗?在对数据进行排序时,已经完成了很多分组工作,然后您可以测试迭代中的当前值是否与最后一个值相差<0.5%,并将itertools.groupby()分解为每次函数返回false时都会有一个新组。