[英]String float to int in python
我有以下数据框:
数据 |
---|
A(1.2,2) |
B(1,5) |
A(5.8, 9) |
乙(8.9,0.9) |
我想将这些 float (str) 对象转换为 int。 我怎么做?
期望输出:
数据 |
---|
A(1,2) |
B(1,5) |
A(6, 9) |
B(9,1) |
到目前为止我尝试了什么?
pd.to_numeric(df['data'])
但我收到以下错误: ValueError: Unable to parse string "A(1,2)" at position 0
我该如何解决这个问题?
您的字符串实际上是namedtuples 。 像这样对待他们
pd.eval()
转换为命名元组df = pd.read_csv(
io.StringIO(
"""df
A(1.2,2)
B(1,5)
A(5.8, 9)
B(8.9,0.9)"""
),
sep="\t",
).rename(columns={"df": "data"})
from collections import namedtuple
A = namedtuple("A", "x y")
B = namedtuple("B", "x y")
df = pd.DataFrame(
{
"data": [
f"{type(nt).__name__}({round(nt.x,0):.0f},{round(nt.y):.0f})"
for nt in pd.eval(df["data"])
]
}
)
map()
进行四舍五入df["data"] = pd.Series(pd.eval(df["data"])).map(
lambda nt: str(nt._replace(x=int(round(nt.x, 0)), y=int(round(nt.y, 0))))
)
数据 | |
---|---|
0 | A(1,2) |
1 | B(1,5) |
2 | A(6,9) |
3 | B(9,1) |
您有一个字符串,首先需要将数字彼此分开,自定义函数可能是最简单的方法:
def round_string(s):
start = s.index('(') +1
stop = s.index(')')
l = s[start:stop].split(',')
lst = [str(int(round(float(i)))) for i in l]
return s[:start] + ','.join(lst) + s[stop:]
s = "B(8.9,0.9)"
round_string(s)
# 'B(9,1)'
将函数映射到数据框:
df['data'].map(round_string)
如果您不需要四舍五入,以下应该可以工作,用空字符串替换小数点和小数点后的数字
df['data'].str.replace('\.\d+', '', regex=True)
0 A(1,2)
1 B(1,5)
2 A(5, 9)
3 B(8,0)
Name: col, dtype: object
为了舍入值,需要更多的努力,只需使用regex
extract
括号部分并将其分配给临时列,然后使用理解来舍入每个值,调用eval
最后替换给定列中的新值。
df.assign(tup=df['data'].str.extract('(\(.*\))')).apply(lambda x: x['data'].replace(x['tup'], str(tuple(round(i) for i in eval(x['tup'])))), axis=1)
0 A(1, 2)
1 B(1, 5)
2 A(6, 9)
3 B(9, 1)
dtype: object
所以你想要做的是将嵌套在字符串内部的浮点数转换为整数。
此外,您的输出表明您不想使用 int 函数,但可能是round(x,0)
(我这样说是因为int(5.8)
计算结果为5
,而不是 6 。
所以像这样应用于数据框的函数将起作用:
def convert_fn_strs(fn):
val_list = re.split('[(,)]',fn)
val_list.remove('')
fn_name = val_list.pop(0)
val_list = [round(float(x)) for i,x in enumerate(val_list)]
return fn_name + str(tuple(val_list))```
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.