Assignment To Containers In Pandas
Solution 1:
Using endemic lists is not allowed on assignment and is not recommended to do this at all.
You can do it if you create from scratch
In [50]: DataFrame({ 'A' : [[],[],1]})
Out[50]:
A
0 []
1 []
21
[3 rows x 1 columns]
The reason this is not allowed is that without indicies (e.g. say in numpy), you can do something like this:
In [51]: df = DataFrame({ 'A' : [1,2,3] })
In [52]: df.loc[df['A'] == 2] = [ 5 ]
In [53]: df
Out[53]:
A
0 1
1 5
2 3
[3 rows x 1 columns]
You can do an assignment where the length of the True values in the mask are equal to the length of the list/tuple/ndarray on the rhs (e.g. the value you are setting). Pandas allows this, as well as a length that is exactly equal to the lhs, and a scalar. Anything else is expressly disallowed because its ambiguous (e.g. do you mean to align it or not?)
For example, imagine:
In [54]: df = DataFrame({ 'A' : [1,2,3] })
In [55]: df.loc[df['A']<3] = [5]
ValueError: cannot set using a list-like indexer with a different length than the value
A 0-length list/tuple/ndarray is considered an error not because it can't be done, but usually its user error, its unclear what to do.
Bottom line, don't use lists inside of a pandas object. Its not efficient, and just makes interpretation difficult / impossible.
Solution 2:
Edit: Preserved my original answer below, but I put it up without testing it and it actually doesn't work for me.
import pandas as pd
import numpy as np
ser1 = pd.Series(['hi',None,np.nan])
ser2 = pd.Series([5,7,9])
df = pd.DataFrame([ser1,ser2]).T
This is janky, I know. Also, apparently the DataFrame constructor (but not the Series constructor) coerces None to np.nan. No idea why.
df.loc[1,0] = None
So now we have
010'hi'51None72 NaN 9
df.columns = ['col1','col2']
mask = np.equal(df['col1'], None)
df.loc[mask, 'col1'] = []
But this doesn't assign anything. The dataframe looks the same as before. I'm following the recommended usage from the docs and assigning base types (strings and numbers) works. So for me the problem is assigning objects to dataframe entries. No idea what's up.
(Original answer)
Two things:
- I'm not familiar with
np.equal
butpandas.isnull()
should also work if you want to capture all null values. - You are doing what is called "chained assignment". I don't understand the problem fully but I know it doesn't work. In the docs.
Try this:
mask = pandas.isnull(df[col])
df.loc[mask, col] = list()
Or, if you only want to catch None
and not np.nan
:
mask = np.equal(df[col].values, None)
df.loc[mask, col] = list()
Note: While pandas.isnull
works with None
on dataframes, series, and arrays as expected, numpy.equal
only works as expected with dataframes and arrays. A pandas Series of all None
will not return True for any of them. This is due to None
only selectively behaving as np.nan
See BUG: None is not equal to None #20442
Post a Comment for "Assignment To Containers In Pandas"