【问题标题】:How replace zero based on specific columns and time value in pandas?如何根据熊猫中的特定列和时间值替换零?
【发布时间】:2021-05-03 14:24:28
【问题描述】:

我正在处理时间序列数据,数据帧示例如下。

输入数据:

|      date        || Device_Id |   | value |
| ---------------- || --------- |   | ----- |
| 28-12-2018 00:00 ||     d1    |   | 0.014 |
| 28-12-2018 00:15 ||     d1    |   | 0.012 |
| 28-12-2018 00:30 ||     d1    |   | 0.012 |
| 28-12-2018 00:45 ||     d1    |   | 0.014 |
| 28-12-2018 01:00 ||     d1    |   | 0.012 |
| 28-12-2018 01:15 ||     d1    |   | 0.012 |
| 28-12-2018 01:30 ||     d1    |   | 0.012 |
| 28-12-2018 01:45 ||     d1    |   | 0.012 |
| 28-12-2018 02:00 ||     d1    |   | 0.014 |
| 28-12-2018 02:15 ||     d1    |   | 0.012 |
|      ....        ||     d1    |   |  ...  |
|        .         ||     .     |   |   .   |
|        .         ||     .     |   |   .   |
| 31-03-2019 23:45 ||     d2    |   |   .   |

预期输出:

|      date        || Device_Id |   | value |
| ---------------- || --------- |   | ----- |
| 28-12-2018 00:00 ||     d1    |   | 0.014 |
| 28-12-2018 00:15 ||     d1    |   | 0.012 |
| 28-12-2018 00:30 ||     d1    |   | 0.012 |
| 28-12-2018 00:45 ||     d1    |   | 0.014 |
| 28-12-2018 01:00 ||     d1    |   |   0   |
| 28-12-2018 01:15 ||     d1    |   |   0   |
| 28-12-2018 01:30 ||     d1    |   |   0   |
| 28-12-2018 01:45 ||     d1    |   |   0   |
| 28-12-2018 02:00 ||     d1    |   |   0   |
| 28-12-2018 02:15 ||     d1    |   |   0   |
|      ....        ||     d1    |   |  ...  |
|        .         ||     .     |   |   .   |
|        .         ||     .     |   |   .   |
| 31-03-2019 23:45 ||     d2    |   |   .   |

我想根据凌晨 1 点到 6 点之间的 Device_Id、日期和时间替换原始数据框中的零值。我试图以不同的方式解决问题,但无法获得预期的结果。以下是我尝试过的代码。

data1['value']=data1.loc[(data1['Device_Id'].str.contains('d1') & data1['date'].str.contains('28-12-2018')), 'value'].between_time('01:00:00', '06:00:00') = 0

上面的代码显示错误“无法分配给函数调用”。之后,我尝试了以下。

data1['value']=data1.loc[(data1['Device_Id'].str.contains('d1') & data1['date'].str.contains('28-12-2018')), 'value'].between_time('01:00:00', '06:00:00') * 0

这可行,但不会更新原始数据框。

【问题讨论】:

  • 要使其在同一个数据帧上工作,您可以尝试使用 inplace=True

标签: python pandas dataframe


【解决方案1】:

使用DatetimeIndex.indexer_between_time 为时间之间的索引创建DatetimeIndex

#if necessary
#data1['date'] = pd.to_datetime(data1['date'])
data1 = data1.set_index('date')

mask = data1['Device_Id'].str.contains('d1') & (data1.index.normalize() == '28-12-2018')
idx = data1[mask].index.indexer_between_time('01:00:00', '06:00:00')

data1.loc[data1[mask].index[idx], 'value'] = 0

print (data1)
                    Device_Id  value
date                                
2018-12-28 00:00:00        d1  0.014
2018-12-28 00:15:00        d1  0.012
2018-12-28 00:30:00        d1  0.012
2018-12-28 00:45:00        d1  0.014
2018-12-28 01:00:00        d1  0.000
2018-12-28 01:15:00        d1  0.000
2018-12-28 01:30:00        d1  0.000
2018-12-28 01:45:00        d1  0.000
2018-12-28 02:00:00        d1  0.000
2018-12-28 02:15:00        d1  0.000

更简单的是使用 Series.between 指定日期时间,因此可以通过掩码设置值:

#if necessary
#data1['date'] = pd.to_datetime(data1['date'])

mask = (data1['Device_Id'].str.contains('d1') & 
        data1['date'].between('28-12-2018 01:00:00', '28-12-2018 06:00:00'))

data1.loc[mask, 'value'] = 0

【讨论】:

  • 上面的代码有问题。它正在将指定时间内的所有设备值更新为零。就像我提供“d1”一样,它应该更新与“d1”关联的值,但它正在更新所有设备值。
  • @RajeshAhir - 您可以更改数据样本以查看问题吗?
  • @RajeshAhir - 因为在示例数据中它工作得很好,所以这意味着一些与数据相关的问题。
  • 不,我正在处理同一个数据集,其中包含许多设备,例如 d1、d2、d3、d4 ......及其相关值。
  • @RajeshAhir - 好的,你可以更改数据以查看问题吗?因为对我来说像需要一样工作 - 只有d1'28-12-2018 01:00:00', '28-12-2018 06:00:00' 之间
猜你喜欢
  • 1970-01-01
  • 2016-04-11
  • 2018-01-10
  • 2021-12-12
  • 2020-04-25
  • 2020-10-21
  • 2018-04-26
  • 2020-05-28
  • 2019-01-24
相关资源
最近更新 更多