代码示例:
In [171]: A = np.array([1.1, 1.1, 3.3, 3.3, 5.5, 6.6])
In [172]: B = np.array([111, 222, 222, 333, 333, 777])
In [173]: C = randint(10, 99, 6)
In [174]: df = pd.DataFrame(zip(A, B, C), columns=['A', 'B', 'C'])
In [175]: df.set_index(['A', 'B'], inplace=True)
In [176]: df
Out[176]:
C
A B
1.1 111 20
222 31
3.3 222 24
333 65
5.5 333 22
6.6 777 74 现在,我想检索A值:
Q1:范围为3.3,6.6 -预期回报值:3.3、5.5、6.6或3.3、3.3、5.5、6.6,如最后一次包括在内,则为3.3、5.5或3.3、3.3、3.3、5.5。
Q2:范围2.0,4.0 -预期回报值: 3.3或3.3,3.3
对于任何其他MultiIndex维度,例如B值,都是相同的:
Q3:在范围111,500有重复,作为范围内预期返回值的数据行数: 111,222,222,333,333。
更正式:
假设T是一个列A、B和C的表,该表包含n行。表格单元格是数字,例如A、B和C整数。让我们为表T创建一个DataFrame,让我们将它命名为DF。让我们设置DF的A和B列索引(没有重复,即没有单独的A和B列作为索引,单独作为数据),在本例中是A和B,即MultiIndex。
问题:
在非索引栏中,我知道上述问题的答案,但在索引的情况下,经过对网络的长期研究和对熊猫功能的实验,我没有成功。我现在看到的唯一方法(没有额外的编程)是,除了索引之外,还有一个重复的A和B作为数据列。
发布于 2013-08-07 12:51:15
通过MultiIndex值查询df,例如(A > 1.7)和(B < 666)
In [536]: result_df = df.loc[(df.index.get_level_values('A') > 1.7) & (df.index.get_level_values('B') < 666)]
In [537]: result_df
Out[537]:
C
A B
3.3 222 43
333 59
5.5 333 56因此,要获得例如“A”的索引值,如果仍然需要的话:
In [538]: result_df.index.get_level_values('A')
Out[538]: Index([3.3, 3.3, 5.5], dtype=object)问题是,在大数据帧中,by索引选择的性能比排序规则行选择差10%。而在重复工作中,循环,延迟累积。见示例:
In [558]: df = store.select(STORE_EXTENT_BURSTS_DF_KEY)
In [559]: len(df)
Out[559]: 12857
In [560]: df.sort(inplace=True)
In [561]: df_without_index = df.reset_index()
In [562]: %timeit df.loc[(df.index.get_level_values('END_TIME') > 358200) & (df.index.get_level_values('START_TIME') < 361680)]
1000 loops, best of 3: 562 µs per loop
In [563]: %timeit df_without_index[(df_without_index.END_TIME > 358200) & (df_without_index.START_TIME < 361680)]
1000 loops, best of 3: 507 µs per loop发布于 2016-11-26 10:44:15
为了获得更好的可读性,我们可以简单地使用 Method,以避免冗长的df.index.get_level_values()和reset_index/set_index往返。
以下是目标DataFrame
In [12]: df
Out[12]:
C
A B
1.1 111 68
222 40
3.3 222 20
333 11
5.5 333 80
6.6 777 51 回答Q1 (A in range [3.3, 6.6]):
In [13]: df.query('3.3 <= A <= 6.6') # for closed interval
Out[13]:
C
A B
3.3 222 20
333 11
5.5 333 80
6.6 777 51
In [14]: df.query('3.3 < A < 6.6') # for open interval
Out[14]:
C
A B
5.5 333 80当然,我们也可以利用<, <=, >, >=进行任何类型的包含。
同样,回答Q2 (A in range [2.0, 4.0]):
In [15]: df.query('2.0 <= A <= 4.0')
Out[15]:
C
A B
3.3 222 20
333 11 回答Q3 (B in range [111, 500]):
In [16]: df.query('111 <= B <= 500')
Out[16]:
C
A B
1.1 111 68
222 40
3.3 222 20
333 11
5.5 333 80而且,您可以非常自然地将与结合起来查询col A和B!
In [17]: df.query('0 < A < 4 and 150 < B < 400')
Out[17]:
C
A B
1.1 222 40
3.3 222 20
333 11发布于 2013-07-29 12:08:22
对于类似于“float”的索引,您总是希望将其用作列而不是直接索引操作。无论端点是否存在,这些都将工作。
In [11]: df
Out[11]:
C
A B
1.1 111 81
222 45
3.3 222 98
333 13
5.5 333 89
6.6 777 98
In [12]: x = df.reset_index()Q1
In [13]: x.loc[(x.A>=3.3)&(x.A<=6.6)]
Out[13]:
A B C
2 3.3 222 98
3 3.3 333 13
4 5.5 333 89
5 6.6 777 98Q2
In [14]: x.loc[(x.A>=2.0)&(x.A<=4.0)]
Out[14]:
A B C
2 3.3 222 98
3 3.3 333 13Q3
In [15]: x.loc[(x.B>=111.0)&(x.B<=500.0)]
Out[15]:
A B C
0 1.1 111 81
1 1.1 222 45
2 3.3 222 98
3 3.3 333 13
4 5.5 333 89如果你想要回指数,就把它们设置好。这是个廉价的行动。
In [16]: x.loc[(x.B>=111.0)&(x.B<=500.0)].set_index(['A','B'])
Out[16]:
C
A B
1.1 111 81
222 45
3.3 222 98
333 13
5.5 333 89如果您真的想要实际的索引值
In [5]: x.loc[(x.B>=111.0)&(x.B<=500.0)].set_index(['A','B']).index
Out[5]:
MultiIndex
[(1.1, 111), (1.1, 222), (3.3, 222), (3.3, 333), (5.5, 333)]https://stackoverflow.com/questions/17921010
复制相似问题