【问题标题】:Pandas: Set first 2 hours of every group to NaNPandas:将每组的前 2 小时设置为 NaN
【发布时间】:2016-06-22 19:54:24
【问题描述】:

我正在尝试通过将每个“状态”组的前 2 小时的“值”设置为 NaN 来清理我的数据。

我的数据框如下所示:

>>> import pandas as pd
>>> import numpy as np
>>> 
>>> rng = pd.date_range('1/1/2016', periods=6, freq='H')
>>> 
>>> data = {'value': np.random.rand(len(rng)), 
...         'state': ['State 1']*3 + ['State 2']*3}
>>> df = pd.DataFrame(data, index=rng)
>>> 
>>> df
                       state     value
2016-01-01 00:00:00  State 1  0.800798
2016-01-01 01:00:00  State 1  0.130290
2016-01-01 02:00:00  State 1  0.464372
2016-01-01 03:00:00  State 2  0.925445
2016-01-01 04:00:00  State 2  0.732331
2016-01-01 05:00:00  State 2  0.811541

我想出了三种方法,但都不起作用:

1) 第一次尝试使用 .loc 和/或 .ix 没有任何变化:

>>> df.loc[df.state=='State 2'].first('2H').value = np.nan
>>> df.ix[df.state=='State 2'].first('2H').value = np.nan
>>> df
                       state     value
2016-01-01 00:00:00  State 1  0.800798
2016-01-01 01:00:00  State 1  0.130290
2016-01-01 02:00:00  State 1  0.464372
2016-01-01 03:00:00  State 2  0.925445
2016-01-01 04:00:00  State 2  0.732331
2016-01-01 05:00:00  State 2  0.811541

2) 第二次尝试导致错误:

>>> df.loc[df.state=='State 2', 'value'].first('2H') = np.nan
  File "<stdin>", line 1
SyntaxError: can't assign to function call

3) 这是一种有效的黑客尝试,但显然不鼓励:

>>> temp = df.loc[df.state=='State 2']
>>> temp.first('2H').value = np.nan
/home/user/anaconda3/lib/python3.5/site-packages/pandas/core/generic.py:2698: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  self[name] = value
>>> df.loc[df.state=='State 2'] = temp
>>> df
                       state     value
2016-01-01 00:00:00  State 1  0.800798
2016-01-01 01:00:00  State 1  0.130290
2016-01-01 02:00:00  State 1  0.464372
2016-01-01 03:00:00  State 2       NaN
2016-01-01 04:00:00  State 2       NaN
2016-01-01 05:00:00  State 2  0.811541

理想情况下,我想确定一种简单的方法来遍历每个组并清理各自数据组的开头和结尾。我的印象是 .first 和 .last 会很棒,因为它们的时间字符串格式很简单。

使用 .loc 并没有考虑到这些时间字符串格式,但我可能遗漏了一些东西。

在 pandas 中这样做的真正方法是什么?

【问题讨论】:

    标签: python python-3.x pandas indexing


    【解决方案1】:

    首先找到所有indexes 2H,然后将index 更改为Multiindexswaplevel 以匹配ix 和最后一个reset_index

    idx = df.groupby('state')['value'].apply(lambda x: x.first('2H')).index
    
    df.set_index('state', append=True, inplace=True)
    df = df.swaplevel(0,1)
    
    df.ix[idx,'value'] = np.nan
    
    print (df.reset_index(level=0))
                           state     value
    2016-01-01 00:00:00  State 1       NaN
    2016-01-01 01:00:00  State 1       NaN
    2016-01-01 02:00:00  State 1  0.406512
    2016-01-01 03:00:00  State 2       NaN
    2016-01-01 04:00:00  State 2       NaN
    2016-01-01 05:00:00  State 2  0.226350
    

    【讨论】:

    • 这个答案假设数据是均匀分布的并按小时索引。我想利用 df.first('2H') 功能来处理独特但间距不一致的数据
    • 难以置信 - 这正是我想要的。
    猜你喜欢
    • 2017-07-19
    • 2022-12-09
    • 2018-08-13
    • 2023-01-24
    • 2014-10-28
    • 2016-12-04
    • 2017-04-03
    • 2020-05-06
    • 2022-07-06
    相关资源
    最近更新 更多