Python Pandas Dataframe: Normalisieren Sie die Daten zwischen 0,01 und 0,99?

Ich versuche, jeden Wert in einem Dataframe zwischen 0,01 und 0,99 zu binden

Ich habe die Daten zwischen 0 und 1 erfolgreich normiert: .apply(lambda x: (x - x.min()) / (x.max() - x.min())) wie folgt:

 df = pd.DataFrame({'one' : ['AAL', 'AAL', 'AAPL', 'AAPL'], 'two' : [1, 1, 5, 5], 'three' : [4,4,2,2]}) df[['two', 'three']].apply(lambda x: (x - x.min()) / (x.max() - x.min())) df 

Jetzt möchte ich alle Werte zwischen 0,01 und 0,99 gebunden haben

Das habe ich versucht:

 def bound_x(x): if x == 1: return x - 0.01 elif x < 0.99: return x + 0.01 df[['two', 'three']].apply(bound_x) 

Df

Aber ich bekomme folgende Fehlermeldung:

 ValueError: ('The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().', u'occurred at index two') 

  • Anhängen von String an den Anfang jedes Wertes in einer Spalte eines Pandas-Dataframs (elegant)
  • Füllen Sie leere Zellen aus früheren Spalten Pandas Python
  • Wie fügt man eine Spalte zu einem Pandas-Dataframe aus Arrays der n-vorhergehenden Werte einer anderen Spalte hinzu?
  • Python: konvertieren numerische daten in pandas dataframe zu floaten in der anwesenheit von strings
  • Warum kann ich keinen Teil meines Pandas DataFrame zuordnen?
  • Wählen Sie Zeilen aus einem DataFrame aus, die auf Werten in einer Spalte in Pandas basieren
  • 2 Solutions collect form web for “Python Pandas Dataframe: Normalisieren Sie die Daten zwischen 0,01 und 0,99?”

    Es gibt eine App, Fehlerclip- Methode , dafür:

     import pandas as pd df = pd.DataFrame({'one' : ['AAL', 'AAL', 'AAPL', 'AAPL'], 'two' : [1, 1, 5, 5], 'three' : [4,4,2,2]}) df = df[['two', 'three']].apply(lambda x: (x - x.min()) / (x.max() - x.min())) df = df.clip(lower=0.01, upper=0.99) 

    Erträge

      two three 0 0.01 0.99 1 0.01 0.99 2 0.99 0.01 3 0.99 0.01 

    Das Problem mit

     df[['two', 'three']].apply(bound_x) 

    bound_x dass bound_x eine Serie wie df['two'] und dann if x == 1 x == 1 in einem booleschen Kontext ausgewertet werden soll . x == 1 ist eine boolesche Serie wie

     In [44]: df['two'] == 1 Out[44]: 0 False 1 False 2 True 3 True Name: two, dtype: bool 

    Python versucht, diese Serie auf einen einzigen booleschen Wert zu reduzieren, True oder False . Pandas folgt der NumPy-Konvention , um einen Fehler zu erheben, wenn du versuchst, eine Serie (oder ein Array) in einen Bool zu konvertieren .

    Also hatte ich ein ähnliches Problem, wo ich maßgeschneiderte Normalisierung wollte, dass ich regelmäßigen Perzentil von Datum oder Z-Score nicht ausreichend war. Manchmal wusste ich, was das Machbare Max und Min der Bevölkerung waren, und wollten es also anders als meine Probe oder einen anderen Mittelpunkt oder was auch immer! So baute ich eine benutzerdefinierte Funktion (benutzte zusätzliche Schritte in den Code hier, um es so lesbar wie möglich zu machen):

     def NormData(s,low='min',center='mid',hi='max',insideout=False,shrinkfactor=0.): if low=='min': low=min(s) elif low=='abs': low=max(abs(min(s)),abs(max(s)))*-1.#sign(min(s)) if hi=='max': hi=max(s) elif hi=='abs': hi=max(abs(min(s)),abs(max(s)))*1.#sign(max(s)) if center=='mid': center=(max(s)+min(s))/2 elif center=='avg': center=mean(s) elif center=='median': center=median(s) s2=[x-center for x in s] hi=hi-center low=low-center center=0. r=[] for x in s2: if x<low: r.append(0.) elif x>hi: r.append(1.) else: if x>=center: r.append((x-center)/(hi-center)*0.5+0.5) else: r.append((x-low)/(center-low)*0.5+0.) if insideout==True: ir=[(1.-abs(z-0.5)*2.) for z in r] r=ir rr =[x-(x-0.5)*shrinkfactor for x in r] return rr 

    Dies wird in einer Pandas-Serie, oder auch nur eine Liste und normalisieren sie auf Ihre angegebenen niedrigen, mittleren und hohen Punkten. Auch da ist ein schrumpffaktor! Um Ihnen zu erlauben, die Daten von 0 und 1 zu verkleinern (das musste ich bei der Kombination von Farbmaps in Matplotlib machen: Single Pcolormesh mit mehr als einer Colormap mit Matplotlib ) So können Sie wahrscheinlich sehen, wie der Code funktioniert, aber im Grunde sagen Sie Werte [-5,1,10] in einer Probe, wollen aber auf Basis eines Bereichs von -7 bis 7 normalisieren (also alles über 7, unser "10" wird als 7 effektiv behandelt) mit einem Mittelpunkt von 2, aber Schrumpfen, um eine 256 RGB Farbkarte zu passen:

     #In[1] NormData([-5,2,10],low=-7,center=1,hi=7,shrinkfactor=2./256) #Out[1] [0.1279296875, 0.5826822916666667, 0.99609375] 

    Es kann auch Ihre Daten von innen nach draußen … das mag seltsam erscheinen, aber ich fand es nützlich für das Hacken. Sagen Sie, Sie wollen eine dunklere Farbe für Werte näher an 0 anstatt hallo / niedrig. Sie können auf der Grundlage normalisierter Daten heizen, wo insideout = True:

     #In[2] NormData([-5,2,10],low=-7,center=1,hi=7,insideout=True,shrinkfactor=2./256) #Out[2] [0.251953125, 0.8307291666666666, 0.00390625] 

    So ist nun "2", das dem Zentrum am nächsten liegt, definiert als "1" ist der höchste Wert.

    Wie auch immer, ich dachte, mein Problem war sehr ähnlich zu Ihnen und diese Funktion könnte für Sie nützlich sein.

    Python ist die beste Programmiersprache der Welt.