我有一个如下列表:
[(220921998, 2426),
(220921999, 2427),
(220922000, 2428),
(220922001, 2429),
(220922563, 2991),
(220922564, 2992),
(220922565, 2993),
(220922566, 2994),
(220922575, 3003),
(220923958, 4386),
(220924161, 4589),
(220924170, 4598),
(220924171, 4599),
(220924172, 4600),
(220924173, 4601),
(220924912, 5340),
(220926340, 6768),
(220926341, 6769),
(220926342, 6770),
(220926343, 6771),
(220926344, 6772),
(220927052, 7480),
(220927053, 7481),
(220927054, 7482),
(220927055, 7483),
(220927056, 7484),
(220927069, 7497),
(220927071, 7499)]
我想根据第二个数字在列表中添加一个字符串。如果列表中的第二个数字在其他第二个数字的20左右之内,则会为它们分配相同的“项目”名称。见下文:
[(220921998, 2426,project1),
(220921999, 2427,project1),
(220922000, 2428,project1),
(220922001, 2429,project1),
(220922563, 2991,project2),
(220922564, 2992,project2),
(220922565, 2993,project2),
(220922566, 2994,project2),
(220922575, 3003,project3),
(220923958, 4386,project4),
(220924161, 4589,project5),
(220924170, 4598,project5),
(220924171, 4599,project5),
(220924172, 4600,project5),
(220924173, 4601,project5),
(220924912, 5340,project6),
(220926340, 6768,project7),
(220926341, 6769,project7),
(220926342, 6770,project7),
(220926343, 6771,project7),
(220926344, 6772,project7),
(220927052, 7480,project8),
(220927053, 7481,project8),
(220927054, 7482,project8),
(220927055, 7483,project8),
(220927056, 7484,project8),
(220927069, 7497,project8),
(220927071, 7499,project8)]
我已经尝试了groupby
,但找不到办法为范围工作。任何帮助都会很棒。谢谢
答案 0 :(得分:5)
将itertools.groupby
与记住最后一项的关键功能一起使用,并使用当前项目进行检查。
lst = [(220921998, 2426),
(220921999, 2427),
(220922000, 2428),
(220922001, 2429),
(220922563, 2991),
(220922564, 2992),
(220922565, 2993),
(220922566, 2994),
(220922575, 3003),
(220923958, 4386),
(220924161, 4589),
....]
class Delta:
def __init__(self, delta):
self.last = None
self.delta = delta
self.key = 1
def __call__(self, value):
if self.last is not None and abs(self.last - value[1]) > self.delta:
# Compare with the last value (`self.last`)
# If difference is larger than 20, advance to next project
self.key += 1
self.last = value[1] # Remeber the last value.
return self.key
import itertools
for key, grp in itertools.groupby(lst, key=Delta(20)):
for tup in grp:
print(tup + ('project{}'.format(key),))
如果使用Python 3.x,则可以使用以下函数(参见nonlocal
):
def Delta(delta):
last = None
key = 1
def keyfunc(value):
nonlocal last, key
if last is not None and abs(last - value[1]) > delta:
key += 1
last = value[1]
return key
return keyfunc
答案 1 :(得分:4)
使用https://pypi.python.org/pypi/cluster/1.1.0b1
>>> import cluster
>>> cl = cluster.HierarchicalClustering(data, lambda x,y: abs(x[1]-y[1]))
>>> cl.getlevel(20)
[
[(220926340, 6768), (220926341, 6769), (220926344, 6772), (220926342, 6770),
(220926343, 6771)],
[(220927052, 7480), (220927053, 7481), (220927056, 7484),
(220927054, 7482), (220927055, 7483), (220927069, 7497), (220927071, 7499)],
[(220921998, 2426), (220921999, 2427), (220922000, 2428), (220922001, 2429)],
[(220922575, 3003), (220922563, 2991), (220922564, 2992), (220922565, 2993),
(220922566, 2994)],
[(220924912, 5340)],
[(220923958, 4386)],
[(220924161, 4589), (220924170, 4598), (220924171, 4599), (220924172, 4600),
(220924173, 4601)]
]
答案 2 :(得分:3)
x=[(220921998, 2426), (220921999, 2427), .... (220927071, 7499)]
start=0
flag=False
num=0
res=[]
for n,t in enumerate(x):
#if not flag:start=x[n][1]
if (x[n][1]-start)<20:
res.append(t+('project%s' %num,))
flag=True
else:
flag=False
start=x[n][1]
num+=1
res.append(t+('project%s' %num,))
print res
返回
[(220921998, 2426, 'project1'),
(220921999, 2427, 'project1'),
(220922000, 2428, 'project1'),
(220922001, 2429, 'project1'),
(220922563, 2991, 'project2'),
(220922564, 2992, 'project2'),
(220922565, 2993, 'project2'),
(220922566, 2994, 'project2'),
(220922575, 3003, 'project2'),
(220923958, 4386, 'project3'),
(220924161, 4589, 'project4'),
(220924170, 4598, 'project4'),
(220924171, 4599, 'project4'),
(220924172, 4600, 'project4'),
(220924173, 4601, 'project4'),
(220924912, 5340, 'project5'),
(220926340, 6768, 'project6'),
(220926341, 6769, 'project6'),
(220926342, 6770, 'project6'),
(220926343, 6771, 'project6'),
(220926344, 6772, 'project6'),
(220927052, 7480, 'project7'),
(220927053, 7481, 'project7'),
(220927054, 7482, 'project7'),
(220927055, 7483, 'project7'),
(220927056, 7484, 'project7'),
(220927069, 7497, 'project7'),
(220927071, 7499, 'project7')]
答案 3 :(得分:3)
以下简单解决方案如何:
data = [(220921998, 2426),
(220921999, 2427),
(220922000, 2428),
(220922001, 2429),
...
(220922563, 2991),
(220922564, 2992)]
ref = 0
cnt = 0
out = []
for dt in data:
if dt[1]-ref > 20:
cnt += 1
ref = dt[1]
out.append((dt[0],dt[1],'project%d'%cnt))
答案 4 :(得分:1)
尝试循环浏览数据:
prev = 0
currentProject = 1;
newx = []
for t[1] in x:
if t - prev <= 20:
pass
else:
currentProject += 1
newx.append((t[0],t[1],"project"+currentProject))
编辑抱歉,我刚才意识到prev=None
不起作用。我本可以检查prev
是否None
,但我认为对于给出的数据,只需执行prev=0
就可以了。谢谢你指出我的错误!