2013-09-29 90 views
0

我有一个数据框,我有一个数字范围。我想查找特定列中的值位于该范围内的行。从满足熊猫条件的数据框中获取行

这似乎是一件小事。我想在这里给出的技术 - 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和熊猫0.12.0

更新:

杰夫的回答工作。

但我觉得isin方法更简单,直观,更少混乱。请评论,如果有人有任何想法为什么失败。

谢谢!

+0

'df_s [df_s.time.isin(range(1379945743843,1379945743845))]'适合我(python 2.7,pandas 0.12。0) –

+0

不知道为什么它不起作用在我的系统上。如果任何人有任何想法,为什么第一个isin'方法失败,请评论。谢谢! – Geekster

回答

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') 

必须使用&和使用的括号

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 

你ISIN方法确实工作。不知道为什么它不适合你。

In [11]: df_s[df_s.time.isin(range(1379945743843,1379945743845))] 
Out[11]: 
      time value 
2 1379945743843  3 
3 1379945743844  4 
+0

谢谢@Jeff!圆括号和'&'做了诡计!它甚至没有转换成实际的时间。进行时间转换有没有好处?我很好奇为什么'isin'技术不能用于我的数据集? – Geekster

+0

正在等待此更新。 'df.query'一定会让生活更轻松。 – Geekster

+0

你的“isin”方法确实有效,不知道为什么它不适合你。 – Jeff