Pythonで5(または他の数)に丸める


162

次のように丸めることができる組み込み関数はありますか?

10 -> 10
12 -> 10
13 -> 15
14 -> 15
16 -> 15
18 -> 20

回答:


304

Pythonの標準関数は知りませんが、これは私にとってはうまくいきます:

Python 2

def myround(x, base=5):
    return int(base * round(float(x)/base))

Python3

def myround(x, base=5):
    return base * round(x/base)

上記が機能する理由は簡単にわかります。5で割った数値が整数であり、正しく丸められていることを確認します。そこで、我々は、最初に正確に(それを行うround(float(x)/5)場所はfloat、私たちは5を掛け、その後、私たちは5で割っただけなのでPython2に必要とされている)にも。への最後の変換intround()、Python 2で浮動小数点値を返すためです。

baseデフォルトで5にパラメーターを指定して、関数をより汎用的にしました。


3
整数と切り捨てのみの場合は、次のようにすることもできますx // base * base
Tjorriemorrie

7
これは私が妄想しているが、私は使用することを好むfloor()ceil()キャストのではなく、:base * floor(x/base)
user666412

1
@ user666412 math.floorおよびmath.ceilカスタムベースでの使用を許可しないため、設定は関係ありません。
Acumenus

48

0.05などの非整数値に丸める場合:

def myround(x, prec=2, base=.05):
  return round(base * round(float(x)/base),prec)

パラメータ値を変更せずに、コード内で検索と置換を行うだけで "round("を "myround(")に変更できるため、これが便利であることがわかりました。


2
あなたは使うことができます:def my_round(x, prec=2, base=0.05): return (base * (np.array(x) / base).round()).round(prec) numpy配列も受け入れます。
saubhik

23

それはスケーリングの問題です

>>> a=[10,11,12,13,14,15,16,17,18,19,20]
>>> for b in a:
...     int(round(b/5.0)*5.0)
... 
10
10
10
15
15
15
15
15
20
20
20

14

「残り」を削除するとうまくいきます:

rounded = int(val) - int(val) % 5

値が整数である場合:

rounded = val - val % 5

関数として:

def roundint(value, base=5):
    return int(value) - int(value) % int(base)

この答えは、最も近い小数値に丸めるのが好きです。つまり、0.25の増分のみが必要な場合。
ジャージー豆


9

round(x [、n]):値は、10の累乗からnを引いた最も近い倍数に丸められます。したがって、nが負の場合...

def round5(x):
    return int(round(x*2, -1)) / 2

10 = 5 * 2なので、5.0での浮動小数点除算と乗算ではなく、2での整数除算と乗算を使用できます。ビットシフトが好きでない限り、それはそれほど重要ではありません

def round5(x):
    return int(round(x << 1, -1)) >> 1

1
+1は、round()が1.0以外の倍数(より高い値を含む)への丸めを処理できることを示します。(ただし、ビットシフトアプローチは浮動小数点数では機能しないことに注意してください。言うまでもなく、ほとんどのプログラマーにとってはあまり読みやすくありません。)
Peter Hansen

1
@ピーターハンセンは+1をありがとう。浮動小数点で動作するビットシフトにはint(x)が必要です。最も読みやすいとは思わなかったので、私はそれを自分では使用しませんが、2や5ではなく、1のみが関係する「純度」が好きでした。
pwdyson、2010

6

申し訳ありませんが、Alok Singhaiの回答についてコメントしたかったのですが、評判が低かったため許可されません= /

とにかく、もう1つのステップを一般化して実行できます。

def myround(x, base=5):
    return base * round(float(x) / base)

これにより、.25やその他の分数の基数など、整数以外の基数を使用できます。


回答としてコメントを投稿して、新しいユーザー制限を回避しようとしないでください。理由は制限があります。これを考えられる理由として考慮してください。なぜ、どのようにして一部の回答が削除されるのでしょうか。
さようならStackExchange 2018年


4

使用する:

>>> def round_to_nearest(n, m):
        r = n % m
        return n + m - r if r + r >= m else n - r

乗算を使用せず、浮動小数点数との間の変換を行いません。

最も近い10の倍数に丸める:

>>> for n in range(-21, 30, 3): print('{:3d}  =>  {:3d}'.format(n, round_to_nearest(n, 10)))
-21  =>  -20
-18  =>  -20
-15  =>  -10
-12  =>  -10
 -9  =>  -10
 -6  =>  -10
 -3  =>    0
  0  =>    0
  3  =>    0
  6  =>   10
  9  =>   10
 12  =>   10
 15  =>   20
 18  =>   20
 21  =>   20
 24  =>   20
 27  =>   30

ご覧のとおり、負の数と正の数の両方で機能します。ネクタイ(例-15および15)は常に上向きに丸められます。

5の最も近い倍数に丸める同様の例は、別の「ベース」でも期待どおりに動作することを示しています。

>>> for n in range(-21, 30, 3): print('{:3d}  =>  {:3d}'.format(n, round_to_nearest(n, 5)))
-21  =>  -20
-18  =>  -20
-15  =>  -15
-12  =>  -10
 -9  =>  -10
 -6  =>   -5
 -3  =>   -5
  0  =>    0
  3  =>    5
  6  =>    5
  9  =>   10
 12  =>   10
 15  =>   15
 18  =>   20
 21  =>   20
 24  =>   25
 27  =>   25

2

誰かが「金融丸め」を必要とする場合(0.5は常に切り上げ):

def myround(x, base=5):
    roundcontext = decimal.Context(rounding=decimal.ROUND_HALF_UP)
    decimal.setcontext(roundcontext)
    return int(base *float(decimal.Decimal(x/base).quantize(decimal.Decimal('0'))))

ドキュメントによると、他の丸めオプションは次のとおりです。

ROUND_CEILING(無限大に向かって)、
ROUND_DOWN(ゼロに向かって)、
ROUND_FLOOR(-Infinityに向かって)、
ROUND_HALF_DOWN(ゼロに
近づくタイに最も近い)、ROUND_HALF_EVEN(タイに最も近い偶数に行くタイに最も近い)、
ROUND_HALF_UP(タイに行く最も近い)ゼロから離れて)、または
ROUND_UP(ゼロから離れて)。
ROUND_05UP(ゼロに向かって丸めた後の最後の桁が0または5の場合はゼロから離れ、それ以外の場合はゼロに向ける)

デフォルトでは、いくつかの統計的な利点があるため、PythonはROUND_HALF_EVENを使用します(丸められた結果にはバイアスがかかりません)。


2

整数およびPython 3の場合:

def divround_down(value, step):
    return value//step*step


def divround_up(value, step):
    return (value+step-1)//step*step

生産:

>>> [divround_down(x,5) for x in range(20)]
[0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15]
>>> [divround_up(x,5) for x in range(20)]
[0, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15, 20, 20, 20, 20]


1

次の5の倍数

51を55に変換する必要があると考えます。

code here

mark = 51;
r = 100 - mark;
a = r%5;
new_mark = mark + a;

1

これが私のCコードです。私がそれを正しく理解していれば、このようなものになるはずです。

#include <stdio.h>

int main(){
int number;

printf("Enter number: \n");
scanf("%d" , &number);

if(number%5 == 0)
    printf("It is multiple of 5\n");
else{
    while(number%5 != 0)
        number++;
  printf("%d\n",number);
  }
}

これも、単に切り上げるのではなく、最も近い5の倍数に丸めます。

#include <stdio.h>

int main(){
int number;

printf("Enter number: \n");
scanf("%d" , &number);

if(number%5 == 0)
    printf("It is multiple of 5\n");
else{
    while(number%5 != 0)
        if (number%5 < 3)
            number--;
        else
        number++;
  printf("nearest multiple of 5 is: %d\n",number);
  }
}

1

これを行う別の方法(明示的な乗算または除算演算子なし):

def rnd(x, b=5):
    return round(x + min(-(x % b), b - (x % b), key=abs))

-3

渡した数値にint()加算0.5することで、切り捨てるのではなく、四捨五入するように「だます」ことができますint()


2
これは実際には質問の答えにはなりません
Uri Agassi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.