如何从DataFrame的DatetimeIndex中提取可迭代的日期字符串列表?
我有一个索引为DatetimeIndex的初始DataFrame df,数据如下:
discharge1 discharge2 datetime 2018-04-25 18:37:00 5862 4427 2018-04-25 21:36:30 6421 4581 2018-04-25 22:13:00 5948 4779 2018-04-26 00:11:30 5703 4314 2018-04-26 02:27:00 4988 3868 2018-04-26 04:28:30 4812 3823 2018-04-26 06:22:30 4347 3672 2018-04-26 10:50:30 3896 3546 2018-04-26 12:04:30 3478 3557 2018-04-26 14:02:30 3625 3598 2018-04-26 15:31:30 3751 3606
我希望把这些日期转换为可迭代的列表/数组/序列,遍历它们并从另一个DataFrame df_other中获取对应行,追加到新DataFrame df_new中,预期的代码逻辑大致是:
for date in date_list(): df_new = df_new.append(df_other.iloc[df_other.index.get_loc(date)])
理想的调用形式是像这样直接用字符串日期:
df_new.append(df_other.iloc[df_other.index.get_loc('2018-04-25 18:37:00')])
但我尝试用df.index获取日期时,返回的是DatetimeIndex,每个元素是Timestamp对象(比如display(df.index[0])返回Timestamp('2018-04-25 18:37:00')),导致append调用失败;用df.index.tolist()得到的仍是Timestamp对象组成的列表,无法满足需求,请问该如何解决?
方法1:把Timestamp转成匹配的字符串格式
这是最直接适配你需求的方式——把DatetimeIndex里的每个时间戳转换成和你示例里一样的字符串格式,这样就能直接和df_other的索引字符串对应上了:
# 生成符合格式的字符串列表 date_list = df.index.strftime('%Y-%m-%d %H:%M:%S').tolist() # 然后遍历操作 df_new = pd.DataFrame() for date in date_list: try: # 直接用loc按索引取值,比iloc+get_loc更简洁 df_new = df_new.append(df_other.loc[date]) except KeyError: # 可以加个异常处理,避免找不到日期时崩溃 print(f"提醒:日期{date}在df_other里找不到哦")
方法2:直接用Timestamp对象匹配(前提是df_other索引也是DatetimeIndex)
其实你之前的问题可能是因为df_other的索引不是DatetimeIndex?如果df_other的索引也是时间戳类型,那完全不用转字符串,直接遍历df.index就行:
df_new = pd.DataFrame() for date in df.index: try: df_new = df_new.append(df_other.loc[date]) except KeyError: print(f"日期{date}不存在于df_other中")
Timestamp对象和DatetimeIndex是天然兼容的,直接用loc就能定位到对应行。
方法3:用批量操作替代循环(强烈推荐)
循环append在数据量稍大的时候会特别慢,pandas本身就支持批量索引,一行代码就能搞定所有操作:
# 如果df_other是DatetimeIndex索引 df_new = df_other.loc[df.index] # 如果df_other是字符串索引,先转df的索引为字符串 df_new = df_other.loc[df.index.strftime('%Y-%m-%d %H:%M:%S')]
要是有部分日期在df_other里不存在,结果里会出现NaN,你可以用df_new = df_new.dropna()把这些无效行删掉,比循环高效太多了!
内容的提问来源于stack exchange,提问作者Johan R

