【问题标题】:String float to int in python在python中将字符串浮点数转换为int
【发布时间】:2021-09-10 16:36:57
【问题描述】:

我有以下数据框:

data
A(1.2,2)
B(1,5)
A(5.8, 9)
B(8.9,0.9)

我想将这些浮点 (str) 对象转换为 int。我该怎么做?

期望的输出:

data
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我该如何解决?

【问题讨论】:

    标签: python pandas floating-point integer


    【解决方案1】:

    您的字符串实际上是namedtuples。这样对待他们

    • 定义预期的命名元组
    • 使用pd.eval()转换成命名元组
    • 使用 f-string 转回想要的字符串表示形式
    • 或者使用Series map() 更改为想要的表示
    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))))
    )
    
    data
    0 A(1,2)
    1 B(1,5)
    2 A(6,9)
    3 B(9,1)

    【讨论】:

      【解决方案2】:

      您有一个字符串,首先需要将数字彼此分开,也许自定义函数可能是最简单的方法:

      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)
      

      【讨论】:

        【解决方案3】:

        如果不需要四舍五入,以下应该可以,用空字符串替换小数点和小数点后的数字

        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
        

        对于四舍五入的值,需要更多的努力,只需 extract 括号部分使用 regex 并将其分配给一个临时列,然后使用理解来四舍五入每个值调用 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
        

        【讨论】:

        • 感谢您的建议。但是,当我尝试执行它时,我收到一条错误消息 SyntaxError: invalid syntax 抱歉这个愚蠢的问题,我该如何解决?
        • 您好@disukumo,我对代码进行了两次测试,使用 Python 3.7.5 和 pandas 1.2.2 运行良好,如果您有的话,一个可能的原因可能是 pandas 旧版本,另一个原因可能是您在问题中拥有的样本数据与您拥有的实际数据不同。
        • 我的python版本是3.8,pandas是1.2.4。不确定,为什么它不起作用。感谢您的帮助!
        【解决方案4】:

        所以你要做的就是将嵌套在字符串中的浮点数转换为整数。

        此外,您的输出表明您不想使用 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))```
        
        
        

        【讨论】:

          猜你喜欢
          • 2011-11-25
          • 2019-07-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-17
          相关资源
          最近更新 更多