Runden Sie in Python auf 5 (oder eine andere Zahl)

162

Gibt es eine eingebaute Funktion, die wie folgt abrunden kann?

10 -> 10
12 -> 10
13 -> 15
14 -> 15
16 -> 15
18 -> 20
Pydev UA
quelle

Antworten:

304

Ich kenne keine Standardfunktion in Python, aber das funktioniert bei mir:

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)

Es ist leicht zu verstehen, warum das oben genannte funktioniert. Sie möchten sicherstellen, dass Ihre durch 5 geteilte Zahl eine ganze Zahl ist, die korrekt gerundet ist. Also machen wir zuerst genau das ( round(float(x)/5)wo floates nur in Python2 benötigt wird) und da wir dann durch 5 teilen, multiplizieren wir auch mit 5. Die endgültige Konvertierung in interfolgt, weil round()in Python 2 ein Gleitkommawert zurückgegeben wird.

Ich habe die Funktion allgemeiner gestaltet, indem ich ihr einen baseParameter mit dem Standardwert 5 gegeben habe.

Alok Singhal
quelle
3
Wenn nur ganze Zahlen und Abrundungen, dann können Sie auch einfach tunx // base * base
Tjorriemorrie
7
Ich bin paranoid, aber ich bevorzuge es zu verwenden floor()und ceil()nicht zu base * floor(x/base)
gießen
1
@ user666412 math.floorund math.ceilerlauben keine Verwendung mit einer benutzerdefinierten Basis, daher ist die Einstellung irrelevant.
Acumenus
48

Zum Runden auf nicht ganzzahlige Werte wie 0,05:

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

Ich fand dies nützlich, da ich einfach in meinem Code suchen und ersetzen konnte, um "round (" in "myround (" zu ändern, ohne die Parameterwerte ändern zu müssen.

CCKx
quelle
2
Sie können def my_round(x, prec=2, base=0.05): return (base * (np.array(x) / base).round()).round(prec) Folgendes verwenden: Dies akzeptiert auch Numpy-Arrays.
Saubhik
23

Es ist nur eine Frage der Skalierung

>>> 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
amo-ej1
quelle
14

Das Entfernen des "Restes" würde funktionieren:

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

Wenn der Wert bereits eine Ganzzahl ist:

rounded = val - val % 5

Als eine Funktion:

def roundint(value, base=5):
    return int(value) - int(value) % int(base)
hgdeoro
quelle
Ich mag diese Antwort zum Runden auf den nächsten Bruchwert. dh wenn ich nur Inkremente von 0,25 will.
Jersey Bean
14
def round_to_next5(n):
    return n + (5 - n) % 5
Andy Wong
quelle
9

rund (x [, n]): Werte werden auf das nächste Vielfache von 10 zur Potenz minus n gerundet. Also wenn n negativ ist ...

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

Da 10 = 5 * 2 ist, können Sie die Ganzzahldivision und -multiplikation mit 2 anstelle der Gleitkommadivision und -multiplikation mit 5,0 verwenden. Nicht, dass das viel ausmacht, es sei denn, Sie mögen Bitverschiebungen

def round5(x):
    return int(round(x << 1, -1)) >> 1
pwdyson
quelle
1
+1, um uns zu zeigen, dass round () Rundungen auf andere Vielfache als 1,0, einschließlich höherer Werte, verarbeiten kann. (Beachten Sie jedoch, dass der Bit-Shifting-Ansatz mit Floats nicht funktioniert, ganz zu schweigen davon, dass er für die meisten Programmierer viel weniger lesbar ist.)
Peter Hansen
1
@ Peter Hansen danke für die +1. Sie benötigen ein int (x), damit die Bitverschiebung mit Floats funktioniert. Einverstanden, nicht das am besten lesbare und ich würde es nicht selbst verwenden, aber ich mochte die "Reinheit" davon nur mit 1 und nicht 2 oder 5.
Pwdyson
6

Entschuldigung, ich wollte die Antwort von Alok Singhai kommentieren, aber es lässt mich nicht, weil ich keinen guten Ruf habe = /

Wie auch immer, wir können noch einen Schritt verallgemeinern und gehen:

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

Dies ermöglicht es uns, nicht ganzzahlige Basen wie .25jede andere gebrochene Basis zu verwenden.

ArturJ
quelle
Bitte versuchen Sie nicht, neue Benutzereinschränkungen zu umgehen, indem Sie einen Kommentar als Antwort veröffentlichen. Einschränkungen bestehen aus einem bestimmten Grund . Berücksichtigen Sie dies als möglichen Grund, warum und wie einige Antworten gelöscht werden.
Auf Wiedersehen StackExchange
4

Modifizierte Version von divround :-)

def divround(value, step, barrage):
    result, rest = divmod(value, step)
    return result*step if rest < barrage else (result+1)*step
Christian Hausknecht
quelle
Verwenden Sie in diesem Fall Divround (Wert 5, 3)? oder vielleicht divround (Wert, 5, 2,5)?
Pwdyson
divround (Wert, 5, 3) genau.
Christian Hausknecht
4

Verwenden:

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

Es verwendet keine Multiplikation und konvertiert nicht von / nach Floats.

Rundung auf das nächste Vielfache von 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

Wie Sie sehen können, funktioniert es sowohl für negative als auch für positive Zahlen. Krawatten (zB -15 und 15) werden immer nach oben gerundet.

Ein ähnliches Beispiel, das auf das nächste Vielfache von 5 gerundet wird und zeigt, dass es sich auch für eine andere "Basis" wie erwartet verhält:

>>> 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
Wouter Polsterlee
quelle
2

Falls jemand eine "finanzielle Rundung" benötigt (0,5 Runden immer auf):

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'))))

Gemäß Dokumentation sind andere Rundungsoptionen:

ROUND_CEILING (in Richtung Unendlichkeit),
ROUND_DOWN (in Richtung Null),
ROUND_FLOOR (in Richtung -Infinity),
ROUND_HALF_DOWN (zum nächsten mit Bindungen gegen Null),
ROUND_HALF_EVEN (zum nächsten mit Bindungen zum nächsten geraden Ganzzahl),
ROUND_HALF_UP (zum nächsten mit Bindungen) weg von Null) oder
ROUND_UP (weg von Null).
ROUND_05UP (von Null weg, wenn die letzte Ziffer nach dem Runden auf Null 0 oder 5 gewesen wäre; andernfalls gegen Null)

Standardmäßig verwendet Python ROUND_HALF_EVEN, da es einige statistische Vorteile bietet (die gerundeten Ergebnisse sind nicht verzerrt).

Piotr Siejda
quelle
2

Für ganze Zahlen und mit Python 3:

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


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

Produzieren:

>>> [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]
Sylvain Leroux
quelle
1

Nächstes Vielfaches von 5

Bedenken Sie, dass 51 in 55 konvertiert werden muss:

code here

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

Hier ist mein C-Code. Wenn ich es richtig verstehe, sollte es so etwas sein;

#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);
  }
}

und dies rundet auch auf das nächste Vielfache von 5, anstatt nur aufzurunden;

#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);
  }
}
Ege Merey
quelle
1

Ein anderer Weg, dies zu tun (ohne explizite Multiplikations- oder Divisionsoperatoren):

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

Sie können int()zum Abrunden „tricksen“ , anstatt abzurunden, indem Sie 0.5die Zahl addieren, an die Sie übergeben int().

Franciska Zsiros
quelle
2
Dies beantwortet nicht wirklich die Frage
Uri Agassi