Python 如何在代码列表中找到较低层次?
我有一个层次代码列表:Python 如何在代码列表中找到较低层次?,python,pandas,Python,Pandas,我有一个层次代码列表: 11000000 11010000 11010100 11010200 11010300 11020000 11020200 11020300 ... 其中11000000是1101的累计总和。。1102.. 等等 最低水平不一定以100、200、300等结束,尽管它不会低于这个水平 有时是: 42000000 42020000 50000000 所以我的问题是:如何自动标记层次结构中的最低级别?我想去掉那些指向累计和的代码 对不起,我应该提供一个更好的解释 较高的代
11000000
11010000
11010100
11010200
11010300
11020000
11020200
11020300
...
其中11000000是1101的累计总和。。1102.. 等等
最低水平不一定以100、200、300等结束,尽管它不会低于这个水平
有时是:
42000000
42020000
50000000
所以我的问题是:如何自动标记层次结构中的最低级别?我想去掉那些指向累计和的代码
对不起,我应该提供一个更好的解释
较高的代码不是其他代码的累积和,它只是指向一个累积和的值
数据={
11000000: 105,
11010000: 50,
11010100: 35,
11010200: 15,
11020000: 55,
11020200: 50,
11020300: 5,
42000000: 150,
42020000: 150,
50000000: 200
}
df=pd.Seriesdata.to_frame.reset_index
df=df.renamecolumns={index:code,0:Value}
代码值
0 11000000 105
1 11010000 50
2 11010100 35
3 11010200 15
4 11020000 55
5 11020200 50
6 11020300 5
7 42000000 150
8 42020000 150
9 50000000 200
如您所见,11000000的值是100,这是11010000和11020000的总和,每个值也是11010100、11010200和11020200、11020300的累积总和
还有42000000,它只包含一个子代码——42020000,因此它们的值相等
最后,像50000000这样的代码可能没有子代码
因此,删除累积代码将得到以下结果:
code Value
2 11010100 35
3 11010200 15
5 11020200 50
6 11020300 5
8 42020000 150
9 50000000 200
这个问题类似于嵌套标题编号,您只希望看到没有其他子标题的标题。 此解决方案基于第一个数字=级别创建一个组,并基于第n个数字递归地分组子组 当一个组中的列表长度为1时,就不可能再进行分组了,我们到达了最后一个子项以及需要过滤掉的父项
from itertools import groupby
codes = [ 11000000, 11010000, 11010100, 11010200, 11010300, 11020000,
11020200, 11020300, 42000000, 42020000, 50000000 ]
def lowest(codes, pos=0, lowcodes=[]):
groups = [ list(lst) for _, lst in groupby(codes, key=lambda x: x[pos])]
for lst in groups:
# print(pos, lst) # uncomment to see what happens during recursion
if len(lst) > 1:
lowest(lst, pos+1)
else:
if lst[0][pos] != '0': # filter out parent
lowcodes.append(int(lst[0]))
continue
return lowcodes
strcodes= [str(code) for code in codes] # use strings instead of ints
print(lowest(strcodes))
印刷品:
[11010100, 11010200, 11010300, 11020200, 11020300, 42020000, 50000000]
线性解
此解决方案首先删除所有正确的填充零,以形成字符串列表['11','1101','110101','110102',…]。然后检查这些部分是否出现在列表中其他元素的开头。如果是这种情况,则它是父元素,可以删除原始列表中的相应元素
codeparts = [ str(code).strip('0') for code in codes ] # ['11', '1101',...]
for i, chk in enumerate(codeparts):
if chk in [code[:len(chk)] for code in codeparts[i+1:]]:
codes.remove(int(chk.ljust(8, '0')))
print(codes)
我不明白这里的逻辑。你怎么看这里的累积总数?@Erfan我更新了最初的帖子。我希望这对你的努力更有意义!我早上第一件事就是试试你的解决方案