我有一个带有第3级多索引的pandas DataFrame。我想在前两个索引中提取“对角线”。即提取前两个索引彼此相等的值,而第三个索引采用所有可能的值。
这是一个示例代码,生成了这样一个DataFrame。
import pandas as pd
import numpy as np
df = pd.DataFrame()
d = 0
e = 1
for A in xrange(3):
for B in xrange(3):
for C in xrange(2):
df = df.append(dict(A=A, B=B, C=C, d=d, e=e), ignore_index=True)
d += 2
e += 2
df.set_index(['A', 'B', 'C'], inplace=True)
df.sortlevel(inplace=True)
print df
然后,DataFrame如下所示:
d e
A B C
0 0 0 0 1
1 2 3
1 0 4 5
1 6 7
2 0 8 9
1 10 11
1 0 0 12 13
1 14 15
1 0 16 17
1 18 19
2 0 20 21
1 22 23
2 0 0 24 25
1 26 27
1 0 28 29
1 30 31
2 0 32 33
1 34 35
我想提取其中A
和B
相等的行(以一种有效的方式,因为实际的DataFrame对于A
和具有100-1000的值B
)。给定上面的示例,我想提取以下DataFrame:
d e
A B C
0 0 0 0 1
1 2 3
1 1 0 16 17
1 18 19
2 2 0 32 33
1 34 35
我已经尝试了以下代码。
ind = np.diag_indices(3) + (slice(None),)
df_diag = df.loc[ind, slice(None)]
print df_diag
它打印:
d e
A B C
0 0 0 0 1
1 2 3
1 0 4 5
1 6 7
2 0 8 9
1 10 11
1 0 0 12 13
1 14 15
1 0 16 17
1 18 19
2 0 20 21
1 22 23
2 0 0 24 25
1 26 27
1 0 28 29
1 30 31
2 0 32 33
1 34 35
如您所见,它只是选择了所有数据。
我的问题是,如何从DataFrame(例如上面给出的行)中以有效的方式提取where中的行A
并B
具有相同的值。
使用以下代码生成更大的数据框:
numAB = 100
numC = 10
num = numAB**2 * numC
A = np.repeat(np.arange(numAB), numAB * numC)
B = np.tile(np.repeat(np.arange(numAB), numC), numAB)
C = np.tile(np.arange(numC), numAB**2)
d = np.arange(num) * 2
e = d + 1
dflarge = pd.DataFrame(dict(A=A, B=B, C=C, d=d, e=e)).set_index(['A', 'B', 'C'])
我测试了@Alexander的答案:
%%timeit
res = pd.concat([dflarge.loc[pd.IndexSlice[n, n, :], :] for n in dflarge.index.levels[0]])
导致:
10 loops, best of 3: 96.7 ms per loop
我测试了@Fabio的答案:
%%timeit
df2 = dflarge.reset_index()
res = df2[df2['A']==df2['B']]
res.set_index(['A', 'B', 'C'], inplace=True)
导致:
100 loops, best of 3: 8.72 ms per loop
后者快约10倍。
我将首先使用以下命令重置数据帧的索引:
df = df.reset_index()
然后执行过滤器以选择所需的内容:
d = df[df['A']==df['B']]
最后再次设置索引:
d.set_index(['A', 'B', 'C'], inplace=True)
这将返回:
d e
A B C
0 0 0 0 1
1 2 3
1 1 0 16 17
1 18 19
2 2 0 32 33
1 34 35
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句