我有一个简单的pandas
系列:
import pandas as pd
quantities = [1, 14, 14, 11, 12, 13, 14]
timestamps = [pd.Timestamp(2015, 4, 1), pd.Timestamp(2015, 4, 1), pd.Timestamp(2015, 4, 2), pd.Timestamp(2015, 4, 3), pd.Timestamp(2015, 4, 4), pd.Timestamp(2015, 4, 5), pd.Timestamp(2015, 4, 8)]
series = pd.Series(quantities, index=timestamps)
如下所示:
2015-04-01 1
2015-04-01 14
2015-04-02 14
2015-04-03 11
2015-04-04 12
2015-04-05 13
2015-04-08 14
dtype: int64
我想填写缺失的日期,即2015-04-06 = NaN
和2015-04-07 = NaN
,但保持序列不变,即:
2015-04-01 1
2015-04-01 14
2015-04-02 14
2015-04-03 11
2015-04-04 12
2015-04-05 13
2015-04-06 NaN
2015-04-07 NaN
2015-04-08 14
dtype: int64
我尝试过:
series = series.asfreq('D')
但出现以下错误: ValueError:无法从重复的轴重新索引。由于时间戳值重复而发生此错误。
地球上有没有办法实现这一目标?
感谢您的帮助。
答案 0 :(得分:4)
让我们尝试一下:
s = pd.Series(np.nan, index=pd.date_range(series.index.min(), series.index.max(), freq='D'))
pd.concat([series,s[~s.index.isin(series.index)]]).sort_index()
输出:
2015-04-01 1.0
2015-04-01 14.0
2015-04-02 14.0
2015-04-03 11.0
2015-04-04 12.0
2015-04-05 13.0
2015-04-06 NaN
2015-04-07 NaN
2015-04-08 14.0
dtype: float64
时间:
%%timeit
temp = series[~series.index.duplicated(keep='first')].asfreq('D')
pd.concat([series, temp.loc[~temp.index.isin(series.index)]]).sort_index()
每个循环2.51 ms±52.7 µs(平均±标准偏差,共运行7次,每个循环100个循环)
%%timeit
series.name = "x"
calendar = pd.DataFrame(None, index=pd.DatetimeIndex(start=series.index.min(), end=series.index.max(), freq='D'))
calendar.join(series)
C:\ ProgramData \ Anaconda3 \ lib \ site-packages \ ipykernel_launcher.py:2: FutureWarning:通过传递范围端点来创建DatetimeIndex是 不推荐使用。请改用
pandas.date_range
。每个循环2.07 ms±27.1 µs(平均±标准偏差,共运行7次,每个循环100个循环)
%%timeit
s = pd.Series(np.nan, index=pd.date_range(series.index.min(), series.index.max(), freq='D'))
pd.concat([series,s[~s.index.isin(series.index)]]).sort_index()
每个循环1.86 ms±15.4 µs(平均±标准偏差,共运行7次,每个循环1000次)
感谢@root的建议。
%%timeit
s = pd.Series(index=pd.date_range(series.index.min(), series.index.max(), freq='D')\
.difference(series.index))
pd.concat([series,s]).sort_index()
每个循环1.55 ms±11.6 µs(平均±标准偏差,共运行7次,每个循环1000次)
答案 1 :(得分:1)
这应该足够了,假设您没有数百万行:
series.name = "x"
calendar = pd.DataFrame(None, index=pd.DatetimeIndex(start=series.index.min(), end=series.index.max(), freq='D'))
calendar.join(series)
输出:
x
2015-04-01 1.0
2015-04-01 14.0
2015-04-02 14.0
2015-04-03 11.0
2015-04-04 12.0
2015-04-05 13.0
2015-04-06 NaN
2015-04-07 NaN
2015-04-08 14.0
如果要进行一系列操作,可以访问结果DataFrame的列x:calendar.join(series).x
答案 2 :(得分:0)
您可以使用pandas.concat
。添加到您的示例代码:
series2 = pd.Series([pd.np.nan, pd.np.nan],
index=[pd.Timestamp(2015, 4, 6),
pd.Timestamp(2015, 4, 7)])
pd.concat([series, series2], axis=0).sort_index()
返回
2015-04-01 1.0
2015-04-01 14.0
2015-04-02 14.0
2015-04-03 11.0
2015-04-04 12.0
2015-04-05 13.0
2015-04-06 NaN
2015-04-07 NaN
2015-04-08 14.0
dtype: float64
也就是说,通过使用非唯一索引,您将面临更多的困难。拥有唯一的索引级别或非索引字段可用于消除歧义,您将受益匪浅。
答案 3 :(得分:0)
您可以使用asfreq
删除索引重复项,然后在{strong>不在原始意甲中的temp.index
处进行合并
temp = series[~series.index.duplicated(keep='first')].asfreq('D')
pd.concat([series, temp.loc[~temp.index.isin(series.index)]]).sort_index()
output:
2015-04-01 1.0
2015-04-01 14.0
2015-04-02 14.0
2015-04-03 11.0
2015-04-04 12.0
2015-04-05 13.0
2015-04-06 NaN
2015-04-07 NaN
2015-04-08 14.0
dtype: float64