【问题标题】:Sampling dataframe Considering NaN values+Pandas采样数据帧考虑 NaN 值+熊猫
【发布时间】:2019-05-07 15:04:27
【问题描述】:

我有一个如下所示的数据框。我想用“3S”做采样 所以有些情况下存在 NaN。我所期望的是数据框应该使用“3S”进行采样,并且如果在两者之间发现任何“NaN”,则停在那里并从该索引开始采样。我尝试使用dataframe.apply 方法来实现,但它看起来很复杂。有什么捷径可以实现吗?

df.sample(n=3)

生成输入的代码:

index = pd.date_range('1/1/2000', periods=13, freq='T')
series = pd.DataFrame(range(13), index=index)
print series

series.iloc[4] = 'NaN'
series.iloc[10] = 'NaN'

我尝试进行采样,但之后不知道如何进行。

2015-01-01 00:00:00    0.0
2015-01-01 01:00:00    1.0
2015-01-01 02:00:00    2.0
2015-01-01 03:00:00    2.0
2015-01-01 04:00:00    NaN
2015-01-01 05:00:00    3.0
2015-01-01 06:00:00    4.0
2015-01-01 07:00:00    4.0
2015-01-01 08:00:00    4.0
2015-01-01 09:00:00    NaN
2015-01-01 10:00:00    3.0
2015-01-01 11:00:00    4.0
2015-01-01 12:00:00    4.0

新的数据框应基于“3S”进行采样,如果存在“NaN”,则应考虑,并从找到“NaN”记录的位置开始采样。

预期输出:

2015-01-01 02:00:00    2.0 -- Sampling after 3S
2015-01-01 03:00:00    2.0 -- Print because NaN has found in Next
2015-01-01 04:00:00    NaN -- print NaN record
2015-01-01 07:00:00    4.0 -- Sampling after 3S
2015-01-01 08:00:00    4.0 -- Print because NaN has found in Next
2015-01-01 09:00:00    NaN -- print NaN record
2015-01-01 12:00:00    4.0 -- Sampling after 3S

【问题讨论】:

  • 所以你想在看到 NaN 的地方重置为 0 并从那里重新采样直到下一个值?
  • 你能告诉我们你希望你的目标df是什么样子吗?
  • 阿西莫,你说得对,我想归零
  • 您的 Expected df 是否有错字?为什么 df 显示 6 am entry after 9 am entry?
  • 是的。有错别字..我会编辑

标签: python pandas dataframe


【解决方案1】:

用途:

index = pd.date_range('1/1/2000', periods=13, freq='H')
df = pd.DataFrame({'col': range(13)}, index=index)
df.iloc[4, 0] = np.nan
df.iloc[9, 0] = np.nan

print (df)
                      col
2000-01-01 00:00:00   0.0
2000-01-01 01:00:00   1.0
2000-01-01 02:00:00   2.0
2000-01-01 03:00:00   3.0
2000-01-01 04:00:00   NaN
2000-01-01 05:00:00   5.0
2000-01-01 06:00:00   6.0
2000-01-01 07:00:00   7.0
2000-01-01 08:00:00   8.0
2000-01-01 09:00:00   NaN
2000-01-01 10:00:00  10.0
2000-01-01 11:00:00  11.0
2000-01-01 12:00:00  12.0

m = df['col'].isna()
s1 = m.ne(m.shift()).cumsum()
t = pd.Timedelta(2, unit='H')
mask = df.index >= df.groupby(s1)['col'].transform(lambda x: x.index[0]) + t

df1 = df[mask | m]
print (df1)
                      col
2000-01-01 02:00:00   2.0
2000-01-01 03:00:00   3.0
2000-01-01 04:00:00   NaN
2000-01-01 07:00:00   7.0
2000-01-01 08:00:00   8.0
2000-01-01 09:00:00   NaN
2000-01-01 12:00:00  12.0

解释:

  1. 创建掩码以通过Series.isna 比较缺失值
  2. 通过将移位值与Series.ne (!=) 进行比较,按连续值创建组

print (s1)
2000-01-01 00:00:00    1
2000-01-01 01:00:00    1
2000-01-01 02:00:00    1
2000-01-01 03:00:00    1
2000-01-01 04:00:00    2
2000-01-01 05:00:00    3
2000-01-01 06:00:00    3
2000-01-01 07:00:00    3
2000-01-01 08:00:00    3
2000-01-01 09:00:00    4
2000-01-01 10:00:00    5
2000-01-01 11:00:00    5
2000-01-01 12:00:00    5
Freq: H, Name: col, dtype: int32
  1. 获取每组索引的第一个值,添加 timdelta(预期输出添加 2T)并通过DatetimeIndex 进行比较
  2. boolean indexing 的最后一个过滤器和| 为bitwise OR 的链式掩码

【讨论】:

    【解决方案2】:

    一种方法是用 0 填充 NA:

    df['Col_of_Interest'] = df['Col_of_Interest'].fillna(0)
    

    然后对系列进行重新采样: (如果 datetime 是您的索引)

    series.resample('30S').asfreq()
    

    【讨论】:

    • 哦,您的预期 df 与我从您的问题中测得的非常不同;我会尽快编辑我的答案
    • 请查看更新后的问题。我已经添加了关于如何生成输入数据框的代码。
    • 您可能需要参考此内容进行条件重采样,以便在此处尝试 dp。stackoverflow.com/questions/48453212/…
    猜你喜欢
    • 2018-03-26
    • 2018-11-16
    • 2022-10-14
    • 1970-01-01
    • 1970-01-01
    • 2017-10-09
    • 2016-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多