cs9*_*s95 14 python sparse-matrix pandas sparse-dataframe
目前的熊猫版: 0.22
我有一个SparseDataFrame.
A = pd.SparseDataFrame(
[['a',0,0,'b'],
[0,0,0,'c'],
[0,0,0,0],
[0,0,0,'a']])
Run Code Online (Sandbox Code Playgroud)
A
0 1 2 3
0 a 0 0 b
1 0 0 0 c
2 0 0 0 0
3 0 0 0 a
Run Code Online (Sandbox Code Playgroud)
现在,填充值是0
.但是,我想将fill_values更改为np.nan
.我的第一直觉是打电话replace
:
A.replace(0, np.nan)
Run Code Online (Sandbox Code Playgroud)
但这给了
TypeError: cannot convert int to an sparseblock
Run Code Online (Sandbox Code Playgroud)
这并没有真正帮助我理解我做错了什么.
我知道我能做到
A.to_dense().replace(0, np.nan).to_sparse()
Run Code Online (Sandbox Code Playgroud)
但有更好的方法吗?或者我对稀疏数据帧的基本理解存在缺陷?
Qus*_*man 15
tl;博士:这绝对是一个错误.
但请继续阅读,还有更多......
所有以下工作都适用于pandas 0.20.3,但不适用于任何较新的版本:
A.replace(0,np.nan)
A.replace({0:np.nan})
A.replace([0],[np.nan])
Run Code Online (Sandbox Code Playgroud)
等......(你明白了).
(从现在开始,所有代码都是用pandas 0.20.3完成的).
然而,那些(以及我尝试过的大多数解决方法)都有效,因为我们不小心做错了什么.如果我们这样做,你会马上猜到:
A.density
1.0
Run Code Online (Sandbox Code Playgroud)
这个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)
Run Code Online (Sandbox Code Playgroud)
现在A.density
将按0.25
预期输出.
发生这种情况是因为初始化程序无法推断列的dtypes.引自熊猫文档:
稀疏数据应与其密集表示具有相同的dtype.目前,支持float64,int64和bool dtypes.根据原始dtype,fill_value默认更改:
- float64:np.nan
- int64:0
- 布尔:错了
但我们的SparseDataFrame的dtypes是:
A.dtypes
0 object
1 object
2 object
3 object
dtype: object
Run Code Online (Sandbox Code Playgroud)
这就是为什么SparseDataFrame无法决定使用哪个填充值,因此使用了默认值np.nan
.
好的,现在我们有一个SparseDataFrame.让我们尝试替换其中的一些条目:
Run Code Online (Sandbox Code Playgroud)
奇怪的是:
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
根据我自己对不同版本的熊猫的实验,它似乎SparseDataFrame.replace()
仅适用于非填充值.要更改填充值,您有以下选项:
DataFrame
,做替换,然后转换回SparseDataFrame
.SparseDataFrame
,如Wen的答案,或者将default_fill_value
set 传递给新的填充值.当我在尝试最后一个选项时,发生了一些更奇怪的事情:
B = pd.SparseDataFrame(A,default_fill_value=np.nan)
B.density
0.25
B.default_fill_value
nan
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.但......:
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
Run Code Online (Sandbox Code Playgroud)
起初这让我很震惊.这甚至可能!?
继续,我试着看看列中发生了什么:
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)
Run Code Online (Sandbox Code Playgroud)
列object
的dtype 是,但BlockIndex
与之关联的dtype 是int32
,因此是奇怪的行为.
还有更多"奇怪"的事情发生,但我会在这里停下来.
从以上所有,我可以说你应该避免使用SparseDataFrame
直到完全重写它发生:).
这就是我所尝试过的
pd.SparseDataFrame(np.where(A==0, np.nan, A))
0 1 2 3
0 a NaN NaN b
1 NaN NaN NaN c
2 NaN NaN NaN NaN
3 NaN NaN NaN a
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
796 次 |
最近记录: |