【问题标题】:set new index for pandas DataFrame (interpolating?)为 pandas DataFrame 设置新索引(插值?)
【发布时间】:2018-01-02 22:55:11
【问题描述】:

我有一个索引不是时间的 DataFrame。我需要将所有值从不等间距的旧索引重新调整为具有不同限制且等间距的新索引。

列中的第一个和最后一个值应保持原样(尽管它们将分配新的、扩展的索引值)。

示例代码为:

import numpy as np
import pandas as pd
%matplotlib inline

index = np.asarray((2, 2.5, 3, 6, 7, 12, 15, 18, 20, 27))
x = np.sin(index / 10)

df = pd.DataFrame(x, index=index)
df.plot();

newindex = np.linspace(0, 29, 100)

如何创建索引为 newindex 且新的 x 值是从旧的 x 值插值的 DataFrame?

第一个新的x 值应该与第一个旧的x 值相同。最后一个 x 值同上。也就是说,开头不应该有 NaN,并且最后一个旧 x 的副本在结尾处重复。

其他的应该被插值以适应新的等间距索引。

我尝试了df.interpolate(),但不知道如何针对newindex 进行插值。

提前感谢您的帮助。

【问题讨论】:

  • 你看过这个问题吗? stackoverflow.com/questions/30056399/…
  • 是的:大多数现有答案(和文档)都有日期或时间索引,但我的没有。如果索引是日期或时间,重新索引似乎要容易得多

标签: pandas numpy interpolation


【解决方案1】:

这很好用:

import numpy as np
import pandas as pd

def interp(df, new_index):
    """Return a new DataFrame with all columns values interpolated
    to the new_index values."""
    df_out = pd.DataFrame(index=new_index)
    df_out.index.name = df.index.name

    for colname, col in df.iteritems():
        df_out[colname] = np.interp(new_index, df.index, col)

    return df_out

【讨论】:

    【解决方案2】:

    我采用了以下解决方案:

    import numpy as np
    import pandas as pd
    import matplotlib.pylab as plt
    
    def reindex_and_interpolate(df, new_index):
        return df.reindex(df.index | new_index).interpolate(method='index', limit_direction='both').loc[new_index]
    
    index = np.asarray((2, 2.5, 3, 6, 7, 12, 15, 18, 20, 27))
    x = np.sin(index / 10)
    
    df = pd.DataFrame(x, index=index)
    
    newindex = pd.Float64Index(np.linspace(min(index)-5, max(index)+5, 50))
    
    df_reindexed = reindex_and_interpolate(df, newindex)
    
    plt.figure()
    plt.scatter(df.index, df.values, color='red', alpha=0.5)
    plt.scatter(df_reindexed.index, df_reindexed.values,  color='green', alpha=0.5)
    plt.show()
    

    【讨论】:

    • NameError: name 'merged_index' is not defined
    • @blokeley 修复了它
    • df.index | new_index 可以导致 FutureWarning: Index.__or__ operating as a set operation is deprecated #codedf.index.union(new_index) 更适合新版本的 Pandas。
    【解决方案3】:

    我想知道您是否遇到了 pandas 的限制之一;似乎您将 df 与任意一组数字(您的 newindex)对齐的选择有限。

    例如,您声明的newindex 仅与index 中的第一个和最后一个数字重叠,因此线性插值(正确)在您的index 的开始 (2) 和结束 (27) 之间插入一条直线.

    import numpy as np
    import pandas as pd
    %matplotlib inline
    
    index = np.asarray((2, 2.5, 3, 6, 7, 12, 15, 18, 20, 27))
    x = np.sin(index / 10)
    
    df = pd.DataFrame(x, index=index)
    
    newindex = np.linspace(min(index), max(index), 100)
    
    df_reindexed = df.reindex(index = newindex)
    df_reindexed.interpolate(method = 'linear', inplace = True)
    
    df.plot()
    df_reindexed.plot()
    

    如果您更改 newindex 以提供更多与原始数据集重叠的点,则插值的工作方式更符合预期:

    newindex = np.linspace(min(index), max(index), 26)
    
    df_reindexed = df.reindex(index = newindex)
    df_reindexed.interpolate(method = 'linear', inplace = True)
    
    df.plot()
    df_reindexed.plot()
    

    还有其他方法不需要手动对齐索引,但生成的曲线(虽然在技术上是正确的)可能不是人们想要的:

    newindex = np.linspace(min(index), max(index), 1000)
    
    df_reindexed = df.reindex(index = newindex, method = 'ffill')
    
    df.plot()
    df_reindexed.plot()
    

    我查看了 pandas 文档,但找不到简单的解决方案。

    https://pandas.pydata.org/pandas-docs/stable/basics.html#basics-reindexing

    【讨论】:

      猜你喜欢
      • 2018-08-02
      • 2016-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-01
      • 2012-11-30
      • 2013-09-23
      • 2018-06-05
      相关资源
      最近更新 更多