【问题标题】:Round to nearest 1000 in pandas在 pandas 中舍入到最近的 1000
【发布时间】:2018-06-05 13:16:18
【问题描述】:

我搜索了 pandas 文档和食谱食谱,很明显您可以使用 dataframe.columnName.round(decimalplace) 轻松四舍五入到最接近的小数位。

如何处理更大的数字?

例如,我有一列房价,我希望它们四舍五入到最接近的 10000 或 1000 或其他值。

df.SalesPrice.WhatDoIDo(1000)? 

【问题讨论】:

  • 除以1000,四舍五入,乘以1000
  • 很多语言都有很多迭代方法来解决这个问题。虽然不乏关于 SO 的“如何舍入”问题,但我一直在寻找一种特定的 pandas 方法来利用这个框架的效率。

标签: python pandas data-science


【解决方案1】:

通过使用符号df.ColumnName.round(),您实际上是在调用pandas.Series.round,其文档指定:

小数:整数

要四舍五入的小数位数(默认值:0)。如果 decimals 为负数,则指定小数点左侧的位数。

所以你可以这样做:

df = pd.DataFrame({'val':[1,11,130,670]})
df.val.round(decimals=-2)

这会产生输出:

0      0
1      0
2    100
3    700
Name: val, dtype: int64

decimals=-3 舍入到 1000,依此类推。值得注意的是,它也可以使用pandas.DataFrame.round(),尽管文档没有告诉你:

df = pd.DataFrame({'val':[1,11,130,670], 'x':[1,11,150,900]})
df.round({'val':-2})

这会将 val 列四舍五入到最接近的 100,但不处理 x

【讨论】:

  • 我完全错过了“如果小数为负数”部分。非常感谢!
【解决方案2】:

你可以试试这个

df = pd.DataFrame({'val':[1,11,130,670]})
10**df.val.astype(str).str.len()
Out[27]: 
0      10
1     100
2    1000
3    1000
Name: val, dtype: int64

【讨论】:

    【解决方案3】:

    函数round 确实接受负值,以便在小数点左侧指定精度:

    dataframe.columnName.round(-3)
    

    例子:

    >>> pd.Series([1, 500, 500.1, 999, 1500, 1501, 946546]).round(-3)
    0         0.0
    1         0.0
    2      1000.0
    3      1000.0
    4      2000.0
    5      2000.0
    6    947000.0
    dtype: float64
    

    【讨论】:

    • 这是正确答案。应该会得到更多的支持。
    【解决方案4】:

    另一个有趣的“技巧”是:假设您想四舍五入到最接近的 100。你可以加 50,然后除以 100,转换成整数,再乘回 100。

    df = pd.DataFrame({'val':[1005,1299,1301,4109]})
    df.val.round(-2) # Proper way
    ((df.val+50)/100).astype(int)*100 # Hack
    

    根据需要为您提供:

    [1000, 1300, 1300, 4100]
    

    【讨论】:

      【解决方案5】:

      我最喜欢的动态方式:

      ds:pd.Series 转为“圆形”
      x:整数/浮点数的幂

      # Define rounding lambda function:
      my_rounder = lambda ds, x: ((ds + 0.5*10**x) // 10**x) * 10**x
      
      # Apply lambda function to "prices" values:
      housing_df["rounded_prices"] = my_rounder(housing_df["prices"], 3)
      
      # If you need to force/ensure no decimal:
      housing_df["rounded_prices"] = housing_df["rounded_prices"].apply(int)
      

      替代地板圆角器:

      my_floor_rounder = lambda ds, x: (ds // 10**x) * 10**x
      

      细分:

      print(housing_df["prices"].head())
      
      year
      2010    372560.0
      2011    374507.0
      2012    376454.0
      2013    378401.0
      2014    380348.0
      Name: prices, dtype: float64
          
      # This step can be omitted if you're finding the floor:
      step_up = housing_df["prices"] + 0.5*10**3
      print(step_up.head())
      
      year
      2010    373060.0
      2011    375007.0
      2012    376954.0
      2013    378901.0
      2014    380848.0
      Name: prices, dtype: float64
      
      thsnd = step_up // 10**3
      print(thsnd.head())
      
      year
      2010    373.0
      2011    375.0
      2012    376.0
      2013    378.0
      2014    380.0
      Name: prices, dtype: float64
      
      rounded = thsnd * 10**3
      print(rounded.head())
      
      year
      2010    373000.0
      2011    375000.0
      2012    376000.0
      2013    378000.0
      2014    380000.0
      Name: prices, dtype: float64
      
      int_rounded = rounded.apply(int)
      print(int_rounded.head())
      
      year
      2010    373000
      2011    375000
      2012    376000
      2013    378000
      2014    380000
      Name: prices, dtype: int64
      

      【讨论】:

        猜你喜欢
        • 2013-04-03
        • 2019-02-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多