我有一个数据框,我有一系列数字。我想找到特定列中的值位于该范围内的行。
这似乎是一项微不足道的工作。我尝试了这里给出的技术 - http://pandas.pydata.org/pandas-docs/dev/indexing.html#indexing-boolean
我举了一个简单的例子:
In [6]: df_s
Out[6]:
time value
0 1 3
1 2 4
2 3 3
3 4 4
4 5 3
5 6 2
6 7 2
7 8 3
8 9 3
In [7]: df_s[df_s.time.isin(range(1,8))]
Out[7]:
time value
0 1 3
1 2 4
2 3 3
3 4 4
4 5 3
5 6 2
6 7 2
然后,我尝试使用我正在使用的数据集中的样本,其中包含时间戳和值作为列:
In [8]: df_s = pd.DataFrame({'time': range(1379945743841,1379945743850), 'value': [3,4,3,4,3,2,2,3,3]})
In [9]: df_s
Out[9]:
time value
0 1379945743841 3
1 1379945743842 4
2 1379945743843 3
3 1379945743844 4
4 1379945743845 3
5 1379945743846 2
6 1379945743847 2
7 1379945743848 3
8 1379945743849 3
In [10]: df_s[df_s.time.isin(range(1379945743843,1379945743845))]
Out[10]:
Empty DataFrame
Columns: [time, value]
Index: []
为什么在这种情况下,相同的技术不起作用?我做错了什么?
我尝试了另一种方法:
In [11]: df_s[df_s.time >= 1379945743843 and df_s.time <=1379945743845]
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-11-45c44def41b4> in <module>()
----> 1 df_s[df_s.time >= 1379945743843 and df_s.time <=1379945743845]
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
然后,我尝试了一些更复杂的方法:
In [13]: df_s.ix[[idx for idx in df_s.index if df_s.ix[idx]['time'] in range(1379945743843, 1379945743845)]]
Out[13]:
time value
2 1379945743843 3
3 1379945743844 4
这给出了期望的结果,但是在原始数据集上给出任何结果需要花费太多时间。它有209920行,当我实际执行代码测试时,预计行数会增加。
任何人都可以指示我采取正确的方法吗?
我使用的是python 2.7.3和pandas 0.12.0
更新
杰夫的回答有效。
但我发现isin
方法更简单,更直观,更简洁。如果有人知道它失败的原因,请发表评论。
谢谢!
答案 0 :(得分:4)
试试这种方式
In [7]: df_s = pd.DataFrame({'time': range(1379945743841,1379945743850), 'value': [3,4,3,4,3,2,2,3,3]})
将您的ms纪元时间戳转换为实际时间
In [8]: df_s['time'] = pd.to_datetime(df_s['time'],unit='ms')
In [9]: df_s
Out[9]:
time value
0 2013-09-23 14:15:43.841000 3
1 2013-09-23 14:15:43.842000 4
2 2013-09-23 14:15:43.843000 3
3 2013-09-23 14:15:43.844000 4
4 2013-09-23 14:15:43.845000 3
5 2013-09-23 14:15:43.846000 2
6 2013-09-23 14:15:43.847000 2
7 2013-09-23 14:15:43.848000 3
8 2013-09-23 14:15:43.849000 3
这些是转换后的终点
In [10]: pd.to_datetime(1379945743843,unit='ms')
Out[10]: Timestamp('2013-09-23 14:15:43.843000', tz=None)
In [11]: pd.to_datetime(1379945743845,unit='ms')
Out[11]: Timestamp('2013-09-23 14:15:43.845000', tz=None)
In [12]: df = df_s.set_index('time')
您必须使用&
并使用parens
In [13]: df_s[(df_s.time>pd.to_datetime(1379945743843,unit='ms')) & (df_s.time<pd.to_datetime(1379945743845,unit='ms'))]
Out[13]:
time value
3 2013-09-23 14:15:43.844000 4
在0.13(即将推出)中,您将能够这样做:
In [7]: df_s.query('"2013-09-23 14:15:43.843" < time < "2013-09-23 14:15:43.845"')
Out[7]:
time value
3 2013-09-23 14:15:43.844000 4
你的方法是否有效。不知道为什么它不适合你。
In [11]: df_s[df_s.time.isin(range(1379945743843,1379945743845))]
Out[11]:
time value
2 1379945743843 3
3 1379945743844 4