【问题标题】:Looking for dataframe.apply() without shape restrictions寻找没有形状限制的 dataframe.apply()
【发布时间】:2013-12-31 04:44:25
【问题描述】:

我想对较小的数据帧时间序列的每一列分别进行样条插值,以创建比原始数据帧更大尺寸的更精细解析的数据帧时间序列。

因此,理想情况下,代码看起来与此类似(在伪代码中):

from scipy.interpolate import UnivariateSpline as Spline
import pandas as pd

few_times = pd.date_range(t0, t1, periods=10)
few_times_for_spline = few_times.values.astype('float')
many_times = pd.date_range(t0, t1, periods=1000)
many_times_for_spline = many_times.values.astype('float')

df_to_interp = pd.DataFrame(randn(10,100), index=few_times)

def do_spline(col):
    return Spline(few_times_for_spline, col)(many_times_for_spline)

df_to_interp.apply(do_spline)

但这给了我错误,因为这些维度不能强制转换为原始数据框维度。我有点困惑为什么它不起作用,因为 df.groupby().apply() 允许更改返回值的维度。

到目前为止,我的解决方案是使用纯 numpy 并使用其函数 apply_along_axis

pd.DataFrame(apply_along_axis(do_spline, 
                              0, 
                              df_to_interp.values), 
             index=many_times, 
             columns=df_to_interp.columns)

但我想知道是否没有更多的panda-esque 解决方案?

【问题讨论】:

    标签: python numpy pandas


    【解决方案1】:

    从 0.13 开始,您应该可以使用 reindexinterpolate 来执行此操作(只要您有 scipy)。

    In [54]: df = pd.DataFrame(np.random.randn(100, 4).cumsum(0)
    , index=pd.DatetimeIndex(start='2010-01-01', freq='s', periods=100))
    
    In [55]: many_idx = pd.DatetimeIndex(start=df.index[0], end=df.index[-1], freq='ms')
    
    In [56]: df.index
    Out[56]: 
    <class 'pandas.tseries.index.DatetimeIndex'>
    [2010-01-01 00:00:00, ..., 2010-01-01 00:01:39]
    Length: 100, Freq: S, Timezone: None
    
    In [57]: many_idx
    Out[57]: 
    <class 'pandas.tseries.index.DatetimeIndex'>
    [2010-01-01 00:00:00, ..., 2010-01-01 00:01:39]
    Length: 99001, Freq: L, Timezone: None
    

    所以现在的想法是 reindex dfmany_idx 并用样条填充生成的 NaNs(分别为每一列)。 pandas/scipy 中似乎存在一个错误,仅执行df.reindex(many_idx).interpolate(method='spline', order=1) 抱怨无法从dtype('&lt;M8[ns]') to dtype('float64') 转换索引dtype,因此作为一种解决方法:

    In [61]: df.reindex(many_idx).reset_index().interpolate(method='spline', order=1).set_index('index')
    Out[61]: 
                                       0         1         2         3
    index                                                             
    2010-01-01 00:00:00        -0.623775  0.069668 -0.010604 -0.201834
    2010-01-01 00:00:00.001000 -0.621875  0.569733  0.081842 -0.278664
    2010-01-01 00:00:00.002000 -0.621800  0.570461  0.081998 -0.278531
    2010-01-01 00:00:00.003000 -0.621725  0.571190  0.082153 -0.278397
    2010-01-01 00:00:00.004000 -0.621651  0.571918  0.082308 -0.278263
    2010-01-01 00:00:00.005000 -0.621576  0.572647  0.082463 -0.278130
    2010-01-01 00:00:00.006000 -0.621502  0.573376  0.082618 -0.277996
    2010-01-01 00:00:00.007000 -0.621427  0.574104  0.082774 -0.277862
    2010-01-01 00:00:00.008000 -0.621352  0.574833  0.082929 -0.277729
    2010-01-01 00:00:00.009000 -0.621278  0.575561  0.083084 -0.277595
    2010-01-01 00:00:00.010000 -0.621203  0.576290  0.083239 -0.277462
    2010-01-01 00:00:00.011000 -0.621128  0.577018  0.083395 -0.277328
    

    这看起来像你想要的吗?

    【讨论】:

    • 感谢您的回答。您是否了解为什么 groupby().apply() 允许返回不同的维度,而 DataFrame.apply() 不允许?
    • 我不完全确定。我认为DataFrame.apply 需要一个减少或返回一维结果的函数。 Groupby.apply 对于返回的内容更加灵活。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多