pandas multiindex dataframe,用于缺失值的ND插值

时间:2015-04-06 04:33:04

标签: python numpy pandas scipy interpolation

pandas是否可以在multiindex数据帧中插入缺失值。以下示例无法按预期工作:

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

3 个答案:

答案 0 :(得分:1)

因此,在填充缺失值之前,这就是前几行中的内容:

df2

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

看起来您想要基于MultiIndex进行插值。我不相信有任何方法可以使用pandas interpolate,但你可以基于一个简单的索引(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插值,你可以很容易地用pandas插值做。如果这还不够,你可以为初学者调查numpy的interp2d

答案 1 :(得分: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()

答案 2 :(得分:0)

根据您拥有的行数,有不同的方式。

我曾经在MAC Pro(16G RAM)上处理7000万行的数据集。我不得不按照product_id,client_id和周数对行进行分组,以计算客户的需求。与您的示例一样,此数据集并不包含每周的所有产品。所以我尝试这些方法:

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

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

  3. 毕竟,我在Stackoverflow上找到了this post。我尝试在空白周中将周数,fillna与" -9999"(一个不存在的数字)重新堆叠并再次堆叠。之后我更换" -9999"与np.nan,然后我得到我想要的。完成它只需要几分钟。我认为这是正确的做法。

  4. 作为结论,如果您的资源有限," reindex"可以只用在一个小数据集上(我用第一种方法来处理一个有500万行的作品,它会在几分钟内返回),除了" unstack / stack" chould适用于更大的数据帧。

相关问题