python - Python Pandas DataFrame:按带有字符串时间戳列表的时间戳列过滤
问题描述
示例设置:
import pandas as pd
df = pd.DataFrame(
data={'ts':
[
'2008-11-05 07:45:23.100',
'2008-11-17 06:53:25.150',
'2008-12-02 07:36:18.643',
'2008-12-15 07:36:24.837',
'2009-01-06 07:03:47.387',
],
'val': range(5)})
df.ts = pd.to_datetime(df.ts)
df.set_index('ts', drop=False, inplace=True)
df
| ts | val
2008-11-05 07:45:23.100 | 2008-11-05 07:45:23.100 | 0
2008-11-17 06:53:25.150 | 2008-11-17 06:53:25.150 | 1
2008-12-02 07:36:18.643 | 2008-12-02 07:36:18.643 | 2
2008-12-15 07:36:24.837 | 2008-12-15 07:36:24.837 | 3
2009-01-06 07:03:47.387 | 2009-01-06 07:03:47.387 | 4
虽然索引是 pd.Timestamp 类型,但我可以使用时间戳的字符串表示来过滤它。例如:
df.loc['2008-11-05']
| ts | val
2008-11-05 07:45:23.100 | 2008-11-05 07:45:23.100 | 0
此外,pandas 带有一个非常方便的功能,当我的过滤器模糊时,它会返回理想的结果。例如:
df.loc['2008-12']
| ts | val
2008-12-02 07:36:18.643 | 2008-12-02 07:36:18.643 | 2
2008-12-15 07:36:24.837 | 2008-12-15 07:36:24.837 | 3
我的第一个问题是,如何使用字符串时间戳列表过滤 df?例如,如果我运行下面的代码
df.loc[['2008-11-05','2008-12']]
,我想要得到的结果是
| ts | val
2008-11-05 07:45:23.100 | 2008-11-05 07:45:23.100 | 0
2008-12-02 07:36:18.643 | 2008-12-02 07:36:18.643 | 2
2008-12-15 07:36:24.837 | 2008-12-15 07:36:24.837 | 3
,但实际上我收到以下错误:
KeyError: "None of [Index(['2008-11-05', '2008-12'], dtype='object', name='ts')] are in the [index]"
我的第二个问题是,我可以对常规列执行类似的过滤逻辑吗?即,如果我不设置ts
为索引而是ts
直接使用字符串过滤器过滤列。
-------------------- 跟进 2019-9-10 10:00 --------------------
非常感谢以下所有答案。不知道pd.Series.str.startswith
能不能支持tuple
多个字符串的输入,还是pd.Series.str.contains
能支持'|'
. 学到了新技能!
我认为所有基于使用的方法astype(str)
对我来说都有一个主要缺点:在美国,人们使用各种日期时间格式。除了'2008-11-05',我公司常用的还有'2008-11-5', '11/05/2008', '11/5/2008', '20081105', '05nov2008'如果我使用基于字符串的方法,一切都会失败。
现在我仍然必须坚持以下方法,它要求列作为索引并且看起来效率不高(我没有分析过),但应该足够健壮。我不明白为什么熊猫本身不支持它。
L = ['5nov2008','2008/12']
pd.concat([df.loc[val] for val in L]).drop_duplicates()
| ts | val
2008-11-05 07:45:23.100 | 2008-11-05 07:45:23.100 | 0
2008-12-02 07:36:18.643 | 2008-12-02 07:36:18.643 | 2
2008-12-15 07:36:24.837 | 2008-12-15 07:36:24.837 | 3
解决方案
这应该开始为你..
>>> df
ts val
0 2008-11-05 07:45:23.100 0
1 2008-11-17 06:53:25.150 1
2 2008-12-02 07:36:18.643 2
3 2008-12-15 07:36:24.837 3
4 2009-01-06 07:03:47.387 4
结果:
>>> df[df.apply(lambda row: row.astype(str).str.contains('2008-11-05')).any(axis=1)]
ts val
0 2008-11-05 07:45:23.100 0
或者 ..
>>> df
ts val
ts
2008-11-05 07:45:23.100 2008-11-05 07:45:23.100 0
2008-11-17 06:53:25.150 2008-11-17 06:53:25.150 1
2008-12-02 07:36:18.643 2008-12-02 07:36:18.643 2
2008-12-15 07:36:24.837 2008-12-15 07:36:24.837 3
2009-01-06 07:03:47.387 2009-01-06 07:03:47.387 4
结果:
>>> df[df.apply(lambda row: row.astype(str).str.contains('2008-11-05')).any(axis=1)]
ts val
ts
2008-11-05 07:45:23.100 2008-11-05 07:45:23.100 0
寻找多个值。
>>> df[df.apply(lambda row: row.astype(str).str.contains('2008-11-05|2008-12')).any(axis=1)]
ts val
ts
2008-11-05 07:45:23.100 2008-11-05 07:45:23.100 0
2008-12-02 07:36:18.643 2008-12-02 07:36:18.643 2
2008-12-15 07:36:24.837 2008-12-15 07:36:24.837 3
推荐阅读
- winapi - 动态数据交换 (DDE) 链路终止
- c++ - PostgreSQL:如何为我的单元测试创建一个临时用户和数据库?
- python - 从管道中读取没有结束
- python - Ceph radosgw - 存储桶策略 - 默认使所有对象公开读取
- haskell - 用 let 和 show 在 haskell 中列出理解,它有什么用?
- css - 如何使用反应在 CSS 内容上获取当前 URL?
- r - 使用总和约束生成排列
- node.js - Dockerizing a React App:应用程序在容器内启动,但无法从暴露的端口访问
- embedded-linux - Buildroot linux内核干净构建
- javascript - 打开file.txt并在输入文本框节点js中显示内容