2017-03-27 2 views
1

Gibt es eine Möglichkeit, in Python mit einem namedtuple füllen?fillna mit einem namedtuple oder anderen Klasse pandas

Ich erhalte diese TypeError:

from collections import namedtuple 
import pandas as pd 
import numpy as np 

df = pd.DataFrame([0, 0, 0, 0, np.nan, 0, 0, 0]) 

nametup = namedtuple('mynp', ['arg1', 'arg2']) 
q = nametup(None, None) 
df.fillna(q) 

Traceback (most recent call last): 
    File "C:\Anaconda2\lib\site-packages\IPython\core\interactiveshell.py", line 2881, in run_code 
    exec(code_obj, self.user_global_ns, self.user_ns) 
    File "<ipython-input-25-363ec560dd77>", line 9, in <module> 
    df.fillna(q) 
    File "C:\Anaconda2\lib\site-packages\pandas\core\frame.py", line 2762, in fillna 
    downcast=downcast, **kwargs) 
    File "C:\Anaconda2\lib\site-packages\pandas\core\generic.py", line 3101, in fillna 
    'you passed a "{0}"'.format(type(value).__name__)) 
TypeError: "value" parameter must be a scalar or dict, but you passed a "mynp" 

auch schon versucht, diese:

df.replace(np.nan, q) 
Traceback (most recent call last): 
    File "C:\Anaconda2\lib\site-packages\IPython\core\interactiveshell.py", line 2881, in run_code 
    exec(code_obj, self.user_global_ns, self.user_ns) 
    File "<ipython-input-31-6f8a86f11bbb>", line 1, in <module> 
    df.replace(np.nan, q) 
    File "C:\Anaconda2\lib\site-packages\pandas\core\generic.py", line 3440, in replace 
    raise TypeError(msg) # pragma: no cover 
TypeError: Invalid "to_replace" type: 'float' 

jede Abhilfe? Vielen Dank!

+0

Genau wie eine Warnung, nicht skalare Einträge werden nicht wirklich von Pandas unterstützt und so wird das Risiko von unerwarteten Bugs. Manchmal ist es trotzdem nützlich, aber ich wurde in der Vergangenheit von einigen gebissen. – DSM

+0

@DSM danke für Einsicht, schau dir mal an, ob ich einen anderen Ansatz verwenden kann. Es ist einfach so praktisch, wenn Sie Klassen nach Datum haben, Pandas zu verwenden. –

Antwort

2

Es ist nicht einfach, aber braucht Series durch Objekte zu erstellen und dann NaN ersetzen:

nametup = namedtuple('mynp', ['arg1', 'arg2']) 
q = nametup(None, None) 

s = pd.Series([q]*len(df.index)) 
print (s) 
0 (None, None) 
1 (None, None) 
2 (None, None) 
3 (None, None) 
4 (None, None) 
5 (None, None) 
6 (None, None) 
7 (None, None) 
dtype: object 

Lösung mit mask:

df[0] = df[0].mask(df[0].isnull(), s) 
print (df) 
       0 
0    0 
1    0 
2    0 
3    0 
4 (None, None) 
5    0 
6    0 
7    0 

Eine andere Lösung mit combine_first oder fillna von Seriess:

df[0] = df[0].combine_first(s) 
#similar solution 
#df[0] = df[0].fillna(s) 
print (df) 
       0 
0    0 
1    0 
2    0 
3    0 
4 (None, None) 
5    0 
6    0 
7    0 
+0

interessante anfahrt danke! –

+0

Btw, dieser Ansatz funktioniert, wenn "NaN" zu leeren Listen ersetzen muss – jezrael

Verwandte Themen