/ / Pandas - замени всички стойности на NaN в DataFrame с празни обекти на python dict - python, pandas

Pandas - заменете всички стойности на NaN в DataFrame с празни обекти на python dict - python, pandas

Имам pandas DataFrame, където всяка клетка съдържа питън 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

Бих искал да замени NN с празен dict, за да получите този резултат:

                    Q          R
X           {2: 2010}  {1: 2013}
Y  {2: 2011, 3: 2009}        {}

Въпреки това, защото fillna функцията тълкува празния dict не като скаларна стойност, а като изобразяване на колоната -> стойност, НЕ НЕ, ако просто правя това (т.е. не работи):

>>> frame.fillna(inplace=True, value={})
Q          R
X           {2: 2010}  {1: 2013}
Y  {2: 2011, 3: 2009}        NaN

Има ли начин да се използва fillna да постигне това, което искам? Трябва ли да повторя през цялата DataFrame или да конструирам глупав dict с всичките ми колони, присвоени на празен dict?

Отговори:

5 за отговор № 1

Успях да използвам DataFrame.applymap по този начин:

>>> 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}         {}

Това решение избягва клопките и в двата случаяРешението на EdChum (където всички NaN клетки завършват, сочейки в същата подлежаща dict обект в паметта, предотвратявайки ги да бъдат осъвременявани независимо един от друг) и Shashank (където потенциално голяма структура на данните трябва да бъде изградена с вложени dits, за да зададете единична празна стойност на dict).


2 за отговор № 2

Проблемът е, че когато се предаде дикт fillna, той се опитва да запълни стойностите въз основа на колоните в рамката. Така че първото решение, което се опитах, беше -

frame.fillna({column: {} for column in frame.columns})

Но ако речникът се предоставя на второ ниво по този начин, той се опитва да съвпадне с клавишите с индекса, така че решението, което работи, е -

frame.fillna({column: {ind: {} for ind in frame.index} for column in frame.columns})

Което дава -

                    Q          R
X           {2: 2010}  {1: 2013}
Y  {2: 2011, 3: 2009}         {}

Отговорът на EdChum вероятно е по-добър за вашите нужди, но това може да се използва, когато не искате да правите промени на място.

EDIT: Решението по-горе работи добре за по-малки кадри, но може да бъде проблем за по-големи рамки. Използвайки replace може да реши това.

frame.replace(np.nan, {column: {} for column in frame.columns})

1 за отговор № 3

Това работи 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 за отговор № 4

употреба .values accessor за директно присвояване в чисто масив:

frame.R = frame.R.astype(object)  # assertion

frame.R.values[frame.R.isnull()] = {}