Mám pandas DataFrame, kde každá bunka obsahuje python dict.
>>> data = {"Q":{"X":{2:2010}, "Y":{2:2011, 3:2009}},"R":{"X":{1:2013}}}
>>> frame = DataFrame(data)
>>> frame
Q R
X {2: 2010} {1: 2013}
Y {2: 2011, 3: 2009} NaN
Chcel by som nahradiť NaN prázdnym kódom, aby ste získali tento výsledok:
Q R
X {2: 2010} {1: 2013}
Y {2: 2011, 3: 2009} {}
Avšak, pretože fillna
funkcia interpretuje prázdne dict nie ako skalárnu hodnotu, ale ako mapovanie stĺpca -> hodnota, to NIE JE, ak to jednoducho urobím (to znamená, že to nefunguje):
>>> frame.fillna(inplace=True, value={})
Q R
X {2: 2010} {1: 2013}
Y {2: 2011, 3: 2009} NaN
Existuje nejaký spôsob použitia fillna
na dosiahnutie toho, čo chcem? Musím opakovať celý DataFrame alebo vytvoriť hlúpe dict so všetkými mojimi stĺpcami mapovanými na prázdne dict?
odpovede:
5 pre odpoveď č. 1Bol som schopný používať DataFrame.applymap
touto cestou:
>>> from pandas import isnull
>>> frame=frame.applymap(lambda x: {} if isnull(x) else x)
>>> frame
Q R
X {2: 2010} {1: 2013}
Y {2: 2011, 3: 2009} {}
Toto riešenie sa vyhýba nástrahám v obidvochRiešenie EdChum (kde všetky bunky NaN vietor ukazujú na rovnaký podkladový objekt dict v pamäti, zabraňujúc ich aktualizácii nezávisle od seba) a Shashankov (kde je potrebné vytvoriť potenciálne veľkú dátovú štruktúru s vnorenými diktátmi, len špecifikovať jednu prázdnu hodnotu dict).
2 pre odpoveď č. 2
Problém je vtedy, keď sa odovzdá dikt fillna
, pokúša sa vyplniť hodnoty založené na stĺpcoch v rámci. Prvé riešenie, ktoré som skúšal,
frame.fillna({column: {} for column in frame.columns})
Ak sa však slovník nachádza na druhej takej úrovni, snaží sa porovnať kľúč s indexom, takže riešenie, ktoré fungovalo,
frame.fillna({column: {ind: {} for ind in frame.index} for column in frame.columns})
Čo dáva -
Q R
X {2: 2010} {1: 2013}
Y {2: 2011, 3: 2009} {}
Odpoveď spoločnosti EdChum je pravdepodobne lepšia pre vaše potreby, ale to môže byť použité, ak nechcete robiť zmeny na mieste.
EDIT: Riešenie vyššie funguje dobre pre menšie rámy, ale môže to byť problém pre väčšie rámy. Použitím replace
to môže vyriešiť.
frame.replace(np.nan, {column: {} for column in frame.columns})
1 pre odpoveď č. 3
Toto funguje loc
:
In [6]:
frame.loc[frame["R"].isnull(), "R"] = {}
frame
Out[6]:
Q R
X {2: 2010} {1: 2013}
Y {2: 2011, 3: 2009} {}
0 pre odpoveď č. 4
použitie .values
príslušenstvo priradiť priamo do čitateľného poľa:
frame.R = frame.R.astype(object) # assertion
frame.R.values[frame.R.isnull()] = {}