熊猫数据帧重新取样基于列标准

yus*_*ica 11 python resampling dataframe pandas

如果另一列中的单元格符合我的条件,我想重新采样数据帧

df = pd.DataFrame({
        'timestamp': [
            '2013-03-01 08:01:00', '2013-03-01 08:02:00',
            '2013-03-01 08:03:00', '2013-03-01 08:04:00',
            '2013-03-01 08:05:00', '2013-03-01 08:06:00'
        ],
        'Kind': [
            'A', 'B', 'A', 'B', 'A', 'B'
        ],
        'Values': [1, 1.5, 2, 3, 5, 3]
    })
Run Code Online (Sandbox Code Playgroud)

对于每个时间戳,我可能有2-10种,我想要正确地重新采样而不产生NaN.目前,我使用下面的代码对整个数据框进行重新采样并得到NaNs.我认为这是因为我有一些特定时间戳的条目.

df.set_index('timestamp').resample('5Min').mean()
Run Code Online (Sandbox Code Playgroud)

一种方法是为每种类型创建不同的数据帧,重新采样每个数据帧,并加入结果数据帧.我想知道是否有任何简单的方法.

Ced*_*olo 5

按照您的说明定义数据框后,您应该将timestamp列转换为datetime第一个。然后将其设置为索引,最后重新采样并找到平均值,如下所示:

import pandas as pd
df = pd.DataFrame({
        'timestamp': [
            '2013-03-01 08:01:00', '2013-03-01 08:02:00',
            '2013-03-01 08:03:00', '2013-03-01 08:04:00',
            '2013-03-01 08:05:00', '2013-03-01 08:06:00'
        ],
        'Kind': [
            'A', 'B', 'A', 'B', 'A', 'B'
        ],
        'Values': [1, 1.5, 2, 3, 5, 3]
    })

df.timestamp = pd.to_datetime(df.timestamp)
df = df.set_index(["timestamp"])
df = df.resample("5Min")    
print df.mean()
Run Code Online (Sandbox Code Playgroud)

这将打印您期望的平均值:

>>> 
Values    2.75
Run Code Online (Sandbox Code Playgroud)

你的数据框会导致:

>>> df
                     Values
timestamp                  
2013-03-01 08:05:00     2.5
2013-03-01 08:10:00     3.0
Run Code Online (Sandbox Code Playgroud)

按种类分组

如果您想按种类分组并获得每种种类的平均值(即 A 和 B),您可以执行以下操作:

df.timestamp = pd.to_datetime(df.timestamp)
df = df.set_index(["timestamp"])
gb = df.groupby(["Kind"])
df = gb.resample("5Min")
print df.xs("A", level = "Kind").mean()
print df.xs("B", level = "Kind").mean()
Run Code Online (Sandbox Code Playgroud)

结果你会得到:

>>> 
Values    2.666667
Values    2.625
Run Code Online (Sandbox Code Playgroud)

您的数据框最终将如下所示:

>>> df
                            Values
Kind timestamp                    
A    2013-03-01 08:05:00  2.666667
B    2013-03-01 08:05:00  2.250000
     2013-03-01 08:10:00  3.000000
Run Code Online (Sandbox Code Playgroud)


igr*_*nis 0

首先,最好将'timestamp'列显式转换为DatetimeIndex类型:

df = pd.DataFrame({
    'timestamp': pd.to_datetime([
        '2013-03-01 08:01:00', '2013-03-01 08:02:00',
        '2013-03-01 08:03:00', '2013-03-01 08:04:00',
        '2013-03-01 08:05:00', '2013-03-01 08:06:00']),
    'Kind':   ['A', 'B', 'A', 'B', 'A', 'B'],
    'Values': [ 1,  4.5,  2,   7,   5,   9] })
Run Code Online (Sandbox Code Playgroud)

请注意Bkind 值的变化。现在,当您重新采样时,mean()会将新值估计为两个现有值的平均值。可能会出现多个新数据点落在现有数据点之间的情况,并pandas用 填充它们的值NaNs。您可以使用ffill()bfill(),具体取决于您希望关闭时间间隔的哪一侧。默认情况下它是保留的,bfill()选择也是如此。

 df.set_index('timestamp').groupby('Kind').resample('1.5Min')['Values'].bfill().reset_index()

Out[1]:

    Kind    timestamp       Values
0   A   2013-03-01 08:00:00 1.0
1   A   2013-03-01 08:01:30 2.0
2   A   2013-03-01 08:03:00 2.0
3   A   2013-03-01 08:04:30 5.0
4   B   2013-03-01 08:01:30 4.5
5   B   2013-03-01 08:03:00 7.0
6   B   2013-03-01 08:04:30 9.0
7   B   2013-03-01 08:06:00 9.0
Run Code Online (Sandbox Code Playgroud)

它将使用最后观察到的值来填充NaNs.

如果您希望对值进行插值,而不仅仅是填补空白,请使用transform(pd.Series.interpolate)组合。将在每个组上transform应用函数。interpolate()尝试以更高的频率(例如 10 秒)重新采样,您会看到两种方法之间的巨大差异。

df = df.set_index('timestamp').groupby('Kind').resample('1.5Min').mean().transform(pd.Series.interpolate).reset_index()

Out[2]:

    Kind    timestamp       Values
0   A   2013-03-01 08:00:00 1.0
1   A   2013-03-01 08:01:30 1.5
2   A   2013-03-01 08:03:00 2.0
3   A   2013-03-01 08:04:30 5.0
4   B   2013-03-01 08:01:30 4.5
5   B   2013-03-01 08:03:00 7.0
6   B   2013-03-01 08:04:30 8.0
7   B   2013-03-01 08:06:00 9.0
Run Code Online (Sandbox Code Playgroud)