为了账号安全,请及时绑定邮箱和手机立即绑定

用浮点数拆分列并在新列中添加整数和小数部分

用浮点数拆分列并在新列中添加整数和小数部分

慕妹3242003 2023-07-18 16:46:06
我有一列(版本号)作为浮点出现超过 200k 次,例如 1.2、0.2 ...我需要将浮点数字的两侧求和到一个新列(总版本)中,以便它在示例中给出3, 2. 只是整数有什么建议吗?
查看完整描述

5 回答

?
绝地无双

TA贡献1946条经验 获得超4个赞

这是一个应该很容易理解的解决方案。我可以制作一个oneline,你也想要那个。


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


查看完整回答
反对 回复 2023-07-18
?
30秒到达战场

TA贡献1828条经验 获得超6个赞

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

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


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

虽然这确实给出了结果,但我认为这是一个坏主意。


问题是,如果您期望得到有意义的结果,则需要显式指定小数部分的精度。"1.20"和"1.2"是相同数字的两个字符串表示形式,但20和2是两个非常不同的整数。此外,浮点数会受到精度误差的影响,您很容易会发现自己使用的是类似 的数字"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

(编辑:还有第三种方法,pandas 的divmod函数。请参阅user2314737 的回答。)


完成此操作后,您可以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


查看完整回答
反对 回复 2023-07-18
?
萧十郎

TA贡献1815条经验 获得超12个赞

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)returns (-4.0, 0.6)。


查看完整回答
反对 回复 2023-07-18
?
慕丝7291255

TA贡献1859条经验 获得超6个赞

以下应该有效:

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


查看完整回答
反对 回复 2023-07-18
?
交互式爱情

TA贡献1712条经验 获得超3个赞

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

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

请注意,我四舍五入为 3 位数字,因为像 2.111 这样的数字已转换为 2.11099999999999999999

然后我只是进行了拆分,为次要版本创建了一个新列(并将主要版本放在原始列中)

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

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

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

(我的数据框名称是 Allfiles 和列版本,正如您可以想象的那样。


查看完整回答
反对 回复 2023-07-18
  • 5 回答
  • 0 关注
  • 126 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信