Python 对于给定的浮点列表,有没有办法找到给定整部分的最大小数部分?

Python 对于给定的浮点列表,有没有办法找到给定整部分的最大小数部分?,python,numpy,Python,Numpy,我遇到了这个问题,在那里我被绊倒了。 问题在于此。 我有这样一份清单: L = [2.1, 2.2, 2.3, 2.4, 2.5, 3.1, 3.2, 3.3, 3.4, 4.1, 4.2, 4.3, 4.4, 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 6.1, 6.2, 6.3, 6.4, 6.5, 7.1, 7.2, 7.3, 7.4, 7.5, 8.1, 8.2, 8.3, 8.4, 8.5, 9.1, 9.2, 9.3, 9.4, 9.5, 10.1, 10.2, 10

我遇到了这个问题,在那里我被绊倒了。
问题在于此。
我有这样一份清单:

L = [2.1, 2.2, 2.3, 2.4, 2.5, 3.1, 3.2, 3.3, 3.4, 4.1, 4.2, 4.3, 4.4, 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 6.1, 6.2, 6.3, 6.4, 6.5, 7.1, 7.2, 7.3, 7.4, 7.5, 8.1, 8.2, 8.3, 8.4, 8.5, 9.1, 9.2, 9.3, 9.4, 9.5, 10.1, 10.2, 10.3, 10.4, 10.5, 11.1, 11.2, 11.3, 11.4, 11.5, 12.1, 12.2, 12.3, 12.4, 12.5]
必填项:
ans=[[2,5],[3,4],[4,4],…]

i、 e.整数和最大小数部分

我们怎样才能做到这一点

到目前为止,我已经尝试过:

# Imports
import numpy as np
import math

L = [2.1, 2.2, 2.3, 2.4, 2.5, 3.1, 3.2, 3.3, 3.4, 4.1, 4.2, 4.3, 4.4, 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 6.1, 6.2, 6.3, 6.4, 6.5, 7.1, 7.2, 7.3, 7.4, 7.5, 8.1, 8.2, 8.3, 8.4, 8.5, 9.1, 9.2, 9.3, 9.4, 9.5, 10.1, 10.2, 10.3, 10.4, 10.5, 11.1, 11.2, 11.3, 11.4, 11.5, 12.1, 12.2, 12.3, 12.4, 12.5]

whole = [ int(str(x).split(".")[0]) for x in L]
frac = [ int(str(x).split(".")[-1]) for x in L]
wf = [[w,f] for w,f in zip(whole,frac)]

wset = list(set(whole))

print(whole)
print(frac)
print(wf)
print(wset)
您可以与按键功能一起使用:

import itertools as it

for k,g in it.groupby(L,lambda x:int(x)):   
    round(max(i % 1 for i in g),1)
结果:

>>> for k,g in it.groupby(L,lambda x:int(x)):
...   print(str(k)+','+str(int(round(max(i % 1 for i in g)*10,1))))
... 
2,5
3,4
4,4
5,6
6,5
7,5
8,5
9,5
10,5
11,5
12,5

您可以向max函数提供一个键函数

max_frac = max(filter(lambda x: int(x) == 2, L), 
               key=lambda x: int(str(x).split(".")[1]))
将模用于此解决方案,如@bernie所做的:

max_frac = max(filter(lambda x: int(x) == 2, L), 
               key=lambda x: x % 1)

编辑:如果要对列表中的每个浮点进行此操作,更好的方法是首先对其进行排序并使用groupby。

如果我正确理解此问题,您可以使用
itertools。groupby

from itertools import groupby

vals = []
foo = [str(e).split('.') for e in L]
for key, group in groupby(foo, lambda x: (x[0])):
    vals.append([int(e) for e in max(group)])

vals
[[2, 5],
 [3, 4],
 [4, 4],
 [5, 6],
 [6, 5],
 [7, 5],
 [8, 5],
 [9, 5],
 [10, 5],
 [11, 5],
 [12, 5]]

下面是一个
numpy
解决方案:

L.sort() # skip this if L is already sorted
Li = L.astype(int)
uniq = np.r_[np.where(np.diff(Li))[0], Li.size-1]
int_part = Li[uniq]
max_frac = np.round((L[uniq]-int_part) * 10).astype(int)
np.c_[int_part, max_frac].tolist()
# [[2, 5], [3, 4], [4, 4], [5, 6], [6, 5], [7, 5], [8, 5], [9, 5], [10, 5], [11, 5], [12, 5]]
一些时间安排:

import numpy as np
import itertools as it
from timeit import timeit

def pp(L):
    Li = L.astype(int)
    uniq = np.r_[np.where(np.diff(Li))[0], Li.size-1]
    int_part = Li[uniq]
    max_frac = np.round((L[uniq]-int_part) * 10).astype(int)
    return np.c_[int_part, max_frac].tolist()

def johnchase(L):
    vals = []
    foo = [str(e).split('.') for e in L]
    for key, group in it.groupby(foo, lambda x: (x[0])):
        vals.append([int(e) for e in max(group)])
    return vals

def bernie(L):
    return [[k, int(round(max(i % 1 for i in g)*10,1))]
            for k, g in it.groupby(L,lambda x:int(x))]

def kprabhakaran(L):
    return [map(int,str(max(list(cgen))).split('.'))
     for c,cgen in it.groupby(L,lambda x:int(x))]

def prep(N, k):
    global L
    L = np.sort(np.random.choice(np.arange(N) / 10, k, False))

N, k, n = 2 * 10**6, 10**6, 10

for func in pp, johnchase, bernie, kprabhakaran:
    print('{:20s}'.format(func.__name__), '{:6.4f} secs'.format(timeit(
        lambda: func(L), lambda: prep(N, k), number=n) / n))
印刷品:

pp                   0.0379 secs
johnchase            1.7252 secs
bernie               1.4773 secs
kprabhakaran         0.7592 secs
您可以在中使用lambda

关于简化列表理解以便更好地理解

print [(c,list(cgen)) for c,cgen in groupby(sorted(L),lambda x:int(x))]
[(2, [2.1, 2.2, 2.3, 2.4, 2.5]), (3, [3.1, 3.2, 3.3, 3.4]), (4, [4.1, 4.2, 4.3, 4.4]), (5, [5.1, 5.2, 5.3, 5.4, 5.5, 5.6]), (6, [6.1, 6.2, 6.3, 6.4, 6.5]), (7, [7.1, 7.2, 7.3, 7.4, 7.5]), (8, [8.1, 8.2, 8.3, 8.4, 8.5]), (9, [9.1, 9.2, 9.3, 9.4, 9.5]), (10, [10.1, 10.2, 10.3, 10.4, 10.5]), (11, [11.1, 11.2, 11.3, 11.4, 11.5]), (12, [12.1, 12.2, 12.3, 12.4, 12.5])]

print [max(list(cgen)) for c,cgen in groupby(sorted(L),lambda x:int(x))]
[2.5, 3.4, 4.4, 5.6, 6.5, 7.5, 8.5, 9.5, 10.5, 11.5, 12.5]

print [str(max(list(cgen))).split('.') for c,cgen in groupby(sorted(L),lambda x:int(x))]
[['2', '5'], ['3', '4'], ['4', '4'], ['5', '6'], ['6', '5'], ['7', '5'], ['8', '5'], ['9', '5'], ['10', '5'], ['11', '5'], ['12', '5']]
所以

L = [2.1, 2.2, 3.1,2.3, 2.4, 2.5, 3.1, 3.2, 3.3, 3.4, 4.1, 4.2, 4.3, 4.4, 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 6.1, 6.2, 6.3, 6.4, 6.5, 7.1, 7.2, 7.3, 7.4, 7.5, 8.1, 8.2, 8.3, 8.4, 8.5, 9.1, 9.2, 9.3, 9.4, 9.5, 10.1, 10.2, 10.3, 10.4, 10.5, 11.1, 11.2, 11.3, 11.4, 11.5, 12.1, 12.2, 12.3, 12.4, 12.5]
from itertools import groupby    
print [map(int,str(max(list(cgen))).split('.')) for c,cgen in groupby(sorted(L),lambda x:int(x))]
输出:

[[2, 5], [3, 4], [4, 4], [5, 6], [6, 5], [7, 5], [8, 5], [9, 5], [10, 5], [11, 5], [12, 5]]

但是,它运行得非常好,如果我在vale上面的for循环中添加另一个打印行。append line:print(key,list(group)),它会给出值ERROR:ValueError:max()arg是一个空序列
group
,在本例中是一个生成器,所以一旦调用它,就必须重新创建它,例如,尝试以下操作:
foo=(范围(10)中的e代表e)对于foo中的i:print(i)
则在不重新运行
foo
分配的情况下再次运行for循环,不会打印任何内容。您可以通过将group变量重新分配给一个列表来解决这个问题:
group=list(group)print(group)
,但是除非必要,否则这将没有那么有效