2015-04-06 87 views
0

熊猫可能在多指标数据帧中插值缺失值。下面的示例不按预期方式工作:熊猫多指标数据帧,缺失值的ND插值

arr1=np.array(np.arange(1.,10.,1.)) 
arr2=np.array(np.arange(2.,20.,2.)) 
df1=pd.DataFrame(zip(arr1,arr2,arr1+arr2,arr1*arr2),columns=['x','y','xplusy','xtimesy']) 

df1.set_index(['x','y'],inplace=True) 

df2=df1.reindex(index=zip(*df1.index.levels)+[(2,2),(3,2),(5,5)]) 
df2.sortlevel([0,1],inplace=True) 
df2.interpolate(method='linear',inplace=True) 

显示不是我预期在xplusy和xtimesy列添加索引。

----------- ---- --- 
(1.0, 2.0) 3  2 
(2.0, 2.0) 4.5 5 
(2.0, 4.0) 6  8 
(3.0, 2.0) 7.5 13 
(3.0, 6.0) 9  18 
(4.0, 8.0) 12  32 
(5.0, 5.0) 13.5 41 
(5.0, 10.0) 15  50 
(6.0, 12.0) 18  72 
(7.0, 14.0) 21  98 
(8.0, 16.0) 24 128 
(9.0, 18.0) 27 162 
----------- ---- --- 

回答

1

所以填充缺失值之前,这是你在第几行:

df2 

     xplusy xtimesy 
x y     
1 2  3  2 
2 2  NaN  NaN 
    4  6  8 

看起来要插值基于多指标的。我不相信有任何方法可以用熊猫插值来做到这一点,但是你可以基于一个简单的索引来做到这一点(method ='linear'忽略索引btw并且也是默认值,所以不需要指定它):

df2.reset_index(level=1).interpolate(method='index') 

    y xplusy xtimesy 
x      
1 2  3  2 
2 2  6  8 
2 4  6  8 

df2.reset_index(level=0).interpolate(method='index') 

    x xplusy xtimesy 
y      
2 1  3.0  2 
2 2  3.0  2 
4 2  6.0  8 

显然,在这种情况下,你可以创建多个步骤xplusy和xtimesy(第一个X,则y,然后xplusy和xtimesy),但我不知道这是你真正想要做的事。

无论如何,这是一种1d插值,你可以用熊猫插值很容易地做到这一点。如果这还不够,你可以看看numpy的interp2d初学者。

+0

我正在寻找ND插值,如scipy中的griddata – denfromufa 2015-04-06 13:48:36

+1

@denfromufa - 你应该将这个问题加入到这个问题中。我也会添加numpy作为标签(而不是数据框)。您可能需要从该问题中删除大熊猫内插,因为它看起来不会在这里有任何用处。当然只是建议。 – JohnE 2015-04-06 13:53:51

+0

我在https://groups.google.com/forum/#!topic/pydata/ido98vCx86Q上发布了这个问题 – denfromufa 2015-04-06 14:35:16

0
def multireindex(_df, new_multi_index, method='linear',copy=True): 
    #from scipy.interpolate import griddata 
    #import numpy as np 
    #import pandas as pd 
    _points=np.array(_df.index.values.tolist()) 
    dfn=dict() 
    for aclm in _df.columns: 
     dfn[aclm] = griddata(_points, _df[aclm], 
         np.array(new_multi_index), method=method) 
    dfn=pd.DataFrame(dfn,index=pd.MultiIndex.from_tuples(
      new_multi_index,names=_df.index.names)) 
    return pd.concat([dfn,_df]) 

import pandas as pd 
import numpy as np 
#import numpy.random as npr 
#df1=pd.DataFrame(npr.rand(10,5)) 
arr1=np.random.rand(100) 
arr2=np.random.rand(100) 
arr1,arr2=[np.round(a*b) for a,b in 
       zip([arr1,arr2],[100,100,1000])] 
df1=pd.DataFrame(zip(arr1,arr2,arr1+arr2,arr1*arr2),columns=['x','y','plus','times']) 
df1.set_index(['x','y'],inplace=True) 
from scipy.interpolate import griddata 
new_points=[(20.0,20.0),(25.0,25.0)] 
df2=multireindex(df1,new_points) 
df2.head() 
0

根据您有多少行有不同的方法。

我用我的MAC Pro(16G RAM)处理7000万行数据集。我必须按照product_id,client_id和星期编号对行进行分组,以计算客户的需求。就像你的例子一样,这个数据集并没有每周的每个产品。所以我尝试以下方法:

  1. 查找每个产品的缺失周数,填写并重新索引。即使将数据集分成几部分,也需要太多的时间和内存来返回结果。

  2. 查找每个产品的缺失周数,创建一个新的数据框,并用原始数据框连接。效率更高,但仍然使用太多时间(几个小时)和内存。

  3. 毕竟我在Stackoverflow上找到this post。我尝试在空白的星期内用“-9999”(一个不存在的数字)填充星期数字,并填充它。之后,我用np.nan替换“-9999”,然后我得到我想要的。它只需要几分钟就可以完成。我认为这是正确的做法。

作为结论,如果你有有限的资源,“重新索引”可能只是一个小的数据集可以使用(我用的是第一种方式来处理500万行的一块,它返回以分钟为单位),除“栈/栈”可以处理更大的数据帧。