【问题标题】:creating categorical data from 2 columns - Python Pandas从 2 列创建分类数据 - Python Pandas
【发布时间】:2018-03-20 13:35:15
【问题描述】:

我在创建一个数据框时遇到问题,该数据框包含一个温度测量值所在的时间间隔。至于现在,数据框的索引为时间,另一列为测量值,我希望将时间转换为间隔 12 小时,测量值是该时间间隔中值的平均值。

                         measurement
time
2016-11-04 08:49:25    17.730000
2016-11-04 10:23:52    18.059999
2016-11-04 11:02:09    18.370001
2016-11-04 12:04:20    18.090000
2016-11-04 14:26:43    18.320000

所以不是每次都与测量相关,我想要的是 12 小时的平均值,如下所示:

                                              measurement
time
2016-11-04 00:00:00 - 2016-11-04 12:00:00     17.730000
2016-11-04 12:00:00 - 2016-11-05 00:00:00     18.059999
2016-11-05 00:00:00 - 2016-11-05 12:00:00     18.370001
2016-11-05 12:00:00 - 2016-11-06 00:00:00     18.090000
2016-11-06 00:00:00 - 2016-11-06 12:00:00     18.320000

有没有一种简单的方法可以用 pandas 做到这一点?

稍后我想将测量值转换为间隔,以便数据变为布尔值,如下所示:

                                              17.0-18.0   18.0-19.0  19.0-20
time
2016-11-04 00:00:00 - 2016-11-04 12:00:00         1           0         0
2016-11-04 12:00:00 - 2016-11-05 00:00:00         0           1         0
2016-11-05 00:00:00 - 2016-11-05 12:00:00         0           1         0
2016-11-05 12:00:00 - 2016-11-06 00:00:00         0           1         0
2016-11-06 00:00:00 - 2016-11-06 12:00:00         0           1         0

编辑: 我使用了 Coldspeed 首次发布的解决方案

df = pd.DataFrame({'timestamp':time.values, 'readings':readings.values})
df = df.groupby(pd.Grouper(key='timestamp', freq='12H'))['readings'].mean()
v = pd.cut(df, bins=[17,18,19,20,21,22,23,24,25,26,27,28], labels=['17-18','18-19','19-20','20-21','21-22','22-23','23-24','24-25','25-26','26-27','27-28'])

我知道垃圾箱和标签可以通过 for 循环完成,但这只是一个快速修复。 groupby 函数以 12 小时为频率对 'timestamp' 的值进行分组,并获取延时中的读数平均值。

然后使用 cut 函数将均值分类到它们的类别中。

结果:

                     17-18  18-19  19-20  20-21  21-22  22-23  23-24  24-25  \
timestamp
2016-11-04 00:00:00      0      1      0      0      0      0      0      0
2016-11-04 12:00:00      0      1      0      0      0      0      0      0
2016-11-05 00:00:00      0      0      0      0      0      0      0      0
2016-11-05 12:00:00      1      0      0      0      0      0      0      0
2016-11-06 00:00:00      1      0      0      0      0      0      0      0
2016-11-06 12:00:00      0      0      0      0      0      0      0      0
2016-11-07 00:00:00      0      1      0      0      0      0      0      0
2016-11-07 12:00:00      1      0      0      0      0      0      0      0
2016-11-08 00:00:00      0      0      0      0      0      0      0      0
2016-11-08 12:00:00      0      0      0      0      0      0      0      0
2016-11-09 00:00:00      1      0      0      0      0      0      0      0
2016-11-09 12:00:00      1      0      0      0      0      0      0      0
2016-11-10 00:00:00      0      1      0      0      0      0      0      0
2016-11-10 12:00:00      0      0      0      0      0      0      0      0
2016-11-11 00:00:00      0      0      0      0      0      0      0      0
2016-11-11 12:00:00      0      0      0      0      0      0      0      0
2016-11-12 00:00:00      0      0      0      0      0      0      0      0
2016-11-12 12:00:00      0      0      0      0      0      0      0      0
2016-11-13 00:00:00      0      0      0      0      0      0      0      0
2016-11-13 12:00:00      0      0      0      0      0      0      0      0
2016-11-14 00:00:00      0      0      0      0      0      0      0      0
2016-11-14 12:00:00      0      1      0      0      0      0      0      0
2016-11-15 00:00:00      0      0      0      1      0      0      0      0
2016-11-15 12:00:00      0      0      0      0      0      1      0      0
2016-11-16 00:00:00      0      0      0      0      0      0      1      0
2016-11-16 12:00:00      0      0      0      0      0      0      0      0
2016-11-17 00:00:00      0      0      0      0      0      0      0      0

【问题讨论】:

标签: python pandas boolean intervals


【解决方案1】:

使用pd.cut + pd.get_dummies:

v = pd.cut(df.measurement, bins=[17, 18, 19, 20], labels=['17-18', '18-19', '19-20'])
pd.get_dummies(v)

   17-18  18-19  19-20
0      1      0      0
1      0      1      0
2      0      1      0
3      0      1      0
4      0      1      0

【讨论】:

    【解决方案2】:

    IIUC 您希望以 12 小时为单位重新采样,然后创建假人。
    pd.cut 是一种完全可以接受的方式,可以将结果数据分割成 bin。
    但是,我使用np.searchsorted 来完成任务。

    bins = np.array([17, 18, 19, 20])
    labels = np.array(['<17', '17-18', '18-19', '19-20', '>20'])
    resampled = df.resample('12H').measurement.mean()
    pd.get_dummies(pd.Series(labels[bins.searchsorted(resampled.values)], resampled.index))
    
                         17-18  18-19  19-20  >20
    2018-03-20 00:00:00      0      1      0    0
    2018-03-20 12:00:00      1      0      0    0
    2018-03-21 00:00:00      0      1      0    0
    2018-03-21 12:00:00      0      0      0    1
    2018-03-22 00:00:00      0      0      1    0
    2018-03-22 12:00:00      0      0      0    1
    

    设置

    np.random.seed(int(np.pi * 1E6))
    
    tidx = pd.date_range(pd.Timestamp('now'), freq='3H', periods=20)
    df = pd.DataFrame(dict(measurement=np.random.rand(len(tidx)) * 6 + 17), tidx)
    
    df
    
                                measurement
    2018-03-20 06:58:30.484383    17.960744
    2018-03-20 09:58:30.484383    18.572100
    2018-03-20 12:58:30.484383    17.646766
    2018-03-20 15:58:30.484383    19.025463
    2018-03-20 18:58:30.484383    17.521399
    2018-03-20 21:58:30.484383    17.318663
    2018-03-21 00:58:30.484383    19.388553
    2018-03-21 03:58:30.484383    19.520969
    2018-03-21 06:58:30.484383    19.060640
    2018-03-21 09:58:30.484383    17.106034
    2018-03-21 12:58:30.484383    22.887546
    2018-03-21 15:58:30.484383    18.437271
    2018-03-21 18:58:30.484383    18.426362
    2018-03-21 21:58:30.484383    20.558928
    2018-03-22 00:58:30.484383    22.555121
    2018-03-22 03:58:30.484383    17.139489
    2018-03-22 06:58:30.484383    17.209499
    2018-03-22 09:58:30.484383    19.466367
    2018-03-22 12:58:30.484383    21.765692
    2018-03-22 15:58:30.484383    19.680785
    

    【讨论】:

      【解决方案3】:

      你可以使用pd.cut() + pd.get_dummies():

      df["measurement"] = pd.cut(df["measurement"], bins=[17.0,18.0,19.0,20.0])
      dummies = pd.get_dummies(df["measurement"])
      

      【讨论】:

        【解决方案4】:

        对于您的第一个问题:您可以使用pandas.TimeGrouper 每 12 小时(或任何其他频率)分组,然后取各组的平均值。

        df.groupby([pd.TimeGrouper(freq='12H')]).mean()

        【讨论】:

          猜你喜欢
          • 2021-11-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-11-13
          • 1970-01-01
          • 1970-01-01
          • 2023-02-02
          • 2022-01-08
          相关资源
          最近更新 更多