Ответ 1
tl; dr: Это определенно ошибка.
Но, пожалуйста, продолжайте читать, есть нечто большее...
Все ниже работает отлично с pandas 0.20.3, но не с какой-либо новой версией:
A.replace(0,np.nan)
A.replace({0:np.nan})
A.replace([0],[np.nan])
и т.д. (вы получаете идею).
(отныне весь код выполняется с помощью pandas 0.20.3).
Однако, те (вместе с большинством обходных решений, которые я пробовал) работают, потому что мы случайно сделали что-то неправильно. Вы угадаете это сразу, если мы это сделаем:
A.density
1.0
Этот SparseDataFrame на самом деле плотный!
Мы можем исправить это, пройдя default_fill_value=0
:
A = pd.SparseDataFrame(
[['a',0,0,'b'],
[0,0,0,'c'],
[0,0,0,0],
[0,0,0,'a']],default_fill_value=0)
Теперь A.density
выведет 0.25
, как ожидалось.
Это произошло потому, что инициализатор не мог вывести dtypes столбцов. Цитирование из pandas docs:
Редкие данные должны иметь тот же тип dtype, что и его плотное представление. В настоящее время поддерживаются типы float64, int64 и bool. В зависимости от исходного типа dtype значение fill_value по умолчанию изменяется:
- float64: np.nan
- int64: 0
- bool: False
Но dtypes нашего SparseDataFrame:
A.dtypes
0 object
1 object
2 object
3 object
dtype: object
И почему SparseDataFrame не может решить, какое значение заливки использовать, и, таким образом, использовало значение по умолчанию np.nan
.
ОК, так что теперь у нас есть SparseDataFrame. Попробуйте заменить некоторые записи в нем:
A.replace('a','z')
0 1 2 3
0 z 0 0 b
1 0 0 0 c
2 0 0 0 0
3 0 0 0 z
И странно:
A.replace(0,np.nan)
0 1 2 3
0 a 0 0 b
1 0 0 0 c
2 0 0 0 0
3 0 0 0 a
И это, как вы можете видеть, неверно! Из моих собственных экспериментов с различными версиями pandas кажется, что
SparseDataFrame.replace()
работает только с значениями, отличными от заполнения.
Чтобы изменить значение заполнения, у вас есть следующие параметры:
- Согласно pandas docs, если вы измените типы dtypes, это автоматически изменит значение заполнения. (Это не сработало со мной).
- Преобразуйте в плотную
DataFrame
, замените, а затем переведите обратно вSparseDataFrame
. - Вручную воссоздайте новый
SparseDataFrame
, например ответ Wen, или передавdefault_fill_value
значение нового значения заполнения.
Пока я экспериментировал с последним вариантом, произошло что-то еще более странное:
B = pd.SparseDataFrame(A,default_fill_value=np.nan)
B.density
0.25
B.default_fill_value
nan
До сих пор так хорошо. Но...:
B
0 1 2 3
0 a 0 0 b
1 0 0 0 c
2 0 0 0 0
3 0 0 0 a
Это действительно шокировало меня поначалу. Это даже возможно!?
Продолжая, я попытался посмотреть, что происходит в столбцах:
B[0]
0 a
1 0
2 0
3 0
Name: 0, dtype: object
BlockIndex
Block locations: array([0], dtype=int32)
Block lengths: array([1], dtype=int32)
dtype столбца object
, но связанный с ним тип BlockIndex
int32
, следовательно, странное поведение.
Происходит гораздо больше "странных" вещей, но я остановлюсь здесь.
Из всего вышеизложенного могу сказать, что вам следует избегать использования SparseDataFrame
до полной перезаписи для него:).