首页 > 解决方案 > 如果不连续有效地添加行:无法从重复轴重新索引

问题描述

我有这个数据。我在这里需要帮助,因为如果您看到时间戳不连续,我想用前一行填充它。

整个数据集的间隔为 30 分钟,因此,如果您查看第 3 行和第 4 行,则存在不连续性,如您所见,在一小时内增加,然后在下一行增加 2 小时。所以我想通过将当前时间戳更改为时间戳+30 来用以前的行值填充缺失的行。

输入数据:

时间戳 eqmt_id 品牌酿造代码 等级 体积
28-03-2021 09:00 1 AB 12.99 1
28-03-2021 09:30 2 BB 123.43 2
28-03-2021 10:00 1 AB 13.34 3
28-03-2021 11:00 1 AB 213.34 1
28-03-2021 14:00 1 AB 12. 322 1

预期结果:

时间戳 eqmt_id 品牌酿造代码 等级 体积
28-03-2021 09:00 1 AB 12.99 1
28-03-2021 09:30 2 BB 123.43 2
28-03-2021 10:00 1 AB 13.34 3
28-03-2021 10:30 1 AB 13.34 3
28-03-2021 11:00 1 AB 213.34 1
28-03-2021 11:30 1 AB 213.34 1
28-03-2021 12:00 1 AB 213.34 1
28-03-2021 12:30 1 AB 213.34 1
28-03-2021 13:00 1 AB 213.34 1
28-03-2021 13:30 1 AB 213.34 1
28-03-2021 14:00 1 AB 12. 322 1

我已经尝试过这段代码,但结果也匹配,但在两者之间停止了。不知道问题。

#dfz is master df

appended_data = []
for i in df.eqmt_id:
  for j in df.brand_brew_no:
    df  = dfz[(dfz['eqmt_id'] == i) & (dfz['brand_brew_no'] == j)]

    df.set_index(pd.to_datetime(df['Timestamp']), inplace=True)
    df2 = df.reindex(
        pd.date_range(df.index.min(), df.index.max(), freq='30min')
    ).fillna(method='ffill')
   
    temp = df2.reset_index()
    appended_data.append(temp)


---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-44-a1a0fbad32b2> in <module>
      4 
      5         df2.set_index(pd.to_datetime(df2['Timestamp']), inplace=True)
----> 6         df2 = pd.DataFrame(df2.reindex(pd.date_range(df2.Timestamp.min(), df2.Timestamp.max(), freq='30min')).fillna(method='ffill'))
      7         temp = df2.reset_index()
    


Error : ValueError: cannot reindex from a duplicate axis

它的到来是因为看起来在主数据中,我们可以有一个前一个时间戳和下一个时间戳相同的行。所以请帮我解决这个问题。

标签: pythonpandas

解决方案


IIUC,你可以试试:

  1. 转换Timestampdatetime.
  2. 设置Timestampindex
  3. 用于asfreq('30T')填充missing time. 与保留的ffill缺失值。downcast = 'infer'dtype
  4. 用于reset_index()获得相同的结构。
df.Timestamp = pd.to_datetime(df.Timestamp)
df = df.set_index('Timestamp')
df = df.asfreq('30T').ffill(downcast='infer').reset_index()

输出:

             Timestamp  eqmt_id brand_brew_code    level  volume
0  2021-03-28 09:00:00        1              AB   12.990       1
1  2021-03-28 09:30:00        2              BB  123.430       2
2  2021-03-28 10:00:00        1              AB   13.340       3
3  2021-03-28 10:30:00        1              AB   13.340       3
4  2021-03-28 11:00:00        1              AB  213.340       1
5  2021-03-28 11:30:00        1              AB  213.340       1
6  2021-03-28 12:00:00        1              AB  213.340       1
7  2021-03-28 12:30:00        1              AB  213.340       1
8  2021-03-28 13:00:00        1              AB  213.340       1
9  2021-03-28 13:30:00        1              AB  213.340       1
10 2021-03-28 14:00:00        1              AB   12.322       1
完整的工作示例:
df = pd.DataFrame(
    {'Timestamp': {0: '28-03-2021 09:00',
                   1: '28-03-2021 09:30',
                   2: '28-03-2021 10:00',
                   3: '28-03-2021 11:00',
                   4: '28-03-2021 14:00'},
     'eqmt_id': {0: 1, 1: 2, 2: 1, 3: 1, 4: 1},
     'brand_brew_code': {0: 'AB', 1: 'BB', 2: 'AB', 3: 'AB', 4: 'AB'},
     'level': {0: 12.99, 1: 123.43, 2: 13.34, 3: 213.34, 4: 12.322},
     'volume': {0: 1, 1: 2, 2: 3, 3: 1, 4: 1}}
)

df.Timestamp = pd.to_datetime(df.Timestamp)
df = df.set_index('Timestamp')
df = df.asfreq('30T').ffill(downcast='infer').reset_index()

注意:这是处理重复时间戳的一种方法->

df = df.sort_values('Timestamp').drop_duplicates('Timestamp' , keep = 'last')

推荐阅读