用浮点数拆分列,并在新列中同时添加int和decimal部分



我有一个列(版本号(,以浮点形式出现了超过200k次,例如1.2、0.2。。。我需要将浮点数的两边求和到一个新的列中(总版本(,这样它就给出了示例3,2。仅整数

有什么建议吗?

这里有一个很容易理解的解决方案。我可以写一行,如果你想要的话。

mylist = [1.3, 2.6, 3.1]
number = 0
fractions = 0
for a in mylist:
(a,b)=str(a).split('.')
number = number + int(a)
fractions = fractions + int(b)
print ("Number: " + str(number))
print ("Fractions: " + str(fractions))

这给出:

Number: 6
Fractions: 10

不要使用str(x).split('.')

一条评论和另外两个答案目前建议使用获得数字x的整数部分和小数部分

i,f = (int(s) for s in str(x).split('.'))

虽然这确实有结果,但我认为这是个坏主意。

问题是,如果您希望得到有意义的结果,则需要明确指定小数部分的精度。"1.20""1.2"是相同数字的两个字符串表示,但202是两个非常不同的整数。此外,浮点数会出现精度误差,您很容易发现自己使用的是像"1.19999999999999999999999"这样的数字,它与"1.2"只有很小的舍入误差,但使用这种str(x).split('.')方法会产生完全不同的结果。

避免这种混乱行为的一种方法是设定一个精度,即小数位数,并坚持下去。例如,在处理货币价值时,我们习惯于谈论美分;虽然1.5欧元和1.50欧元在技术上都是有效的,但你总是会听到人们说";一欧元五十";并且从不";一欧元五";。如果你听到有人说";一欧元哦五欧元";,实际上它的意思是1.05欧元。我们总是加两位小数。

用这种方法,1.2不存在变为(1,2)(1,20)(1,1999999999)的混沌行为。如果将小数位数固定为2,则1.2将始终映射到(1,20),仅此而已。

更标准的方式

以下是在python中获取数字的整数和小数部分的两种标准方法:

x = 1.20
# method 1
i = int(x)
f = x - i
# i = 1 and f = 0.2; i is an int and f a float
# method 2
import math
f, i = math.modf(x)
# i = 1.0 and f = 0.2; i and f are both floats

(编辑:还有第三种方法,熊猫的divmod函数。请参阅用户2314737的答案。(

完成后,您可以将分数部分f乘以所选的10次方,然后将其转换为整数:

f = int(f * 100)
# f = 20

最后,您可以将此方法应用于整个列表:

data = [13.0, 14.20, 12.299, 4.414]
def intfrac_pair(x, decimal_places):
i = int(x)
f = int((10**decimal_places) * (x - i))
return (i, f)
data_as_pairs = [intfrac_pair(x, 2) for x in data]
# = [(13, 0), (14, 20), (12, 30), (4, 41)]
sum_of_integer_parts    = sum(i for i,f in data_as_pairs)  # = 43
sum_of_fractional_parts = sum(f for i,f in data_as_pairs)  # = 91

以下内容应该有效:

df['total_number']=[sum([int(i) for i in str(k).split('.')]) for k in df.version_number]

您可以在列上使用divmod

df = pd.DataFrame([1.2, 2.3, 3.4, 4.5, 0.1])                           
df                                                                      
#      0
# 0  1.2
# 1  2.3
# 2  3.4
# 3  4.5
# 4  0.1
df['i'], df['d'] = df[0].divmod(1)                                     
df                                                                     
# Out: 
#      0    i    d
# 0  1.2  1.0  0.2
# 1  2.3  2.0  0.3
# 2  3.4  3.0  0.4
# 3  4.5  4.0  0.5
# 4  0.1  0.0  0.1

要按行求和为整数(需要精度,这里我使用p=1,假设原始浮点只包含一个十进制数字(:

p = 1
df['s'] = (df['i']+10**p*df['d'].round(decimals=p)).astype(np.int)
df                                                                    
# Out: 
#      0    i    d  s
# 0  1.2  1.0  0.2  3
# 1  2.3  2.0  0.3  5
# 2  3.4  3.0  0.4  7
# 3  4.5  4.0  0.5  9
# 4  0.1  0.0  0.1  1

按列求和:

df.sum()                                                               
# Out: 
# 0    11.5
# i    10.0
# d     1.5

注意:这只适用于正整数,例如divmod(-3.4, 1)返回(-4.0, 0.6)

谢谢大家。我终于以一种相当愚蠢但有效的方式成功了。在拆分之前,我将其转换为字符串:

Allfiles['Version'] = Allfiles['Version'].round(3).astype(str)

注意,我四舍五入到3位,因为像2.111这样的数字被转换为2.1109999999999999999

然后我只是做了拆分,为次要版本创建了一个新的专栏(并在原始专栏中包含主要版本

Allfiles[['Version', 'minor']] = Allfiles['Version'].str.split('.', expand=True)

然后,我再次将这两个文件转换为整数,并在第一列中对两者求和。

Allfiles['Version'] = Allfiles['Version']+Allfiles['minor']

(正如你所能想象的,我的数据帧名称是Allfiles和列版本

最新更新