使多索引熊猫数据帧不对称

时间:2020-01-10 05:45:00

标签: python pandas dataframe

我有一个多索引数据框,看起来像这样:

import pandas as pd

test = pd.DataFrame({('A', 'a'):[1,2,3,4,5], ('A', 'b'):[5,4,3,2,1], ('B', 'a'):[5,2,3,4,1], ('B','b'):[1,4,3,2,5]})
>>> Output

   A     B   
   a  b  a  b
0  1  5  5  1
1  2  4  2  4
2  3  3  3  3
3  4  2  4  2
4  5  1  1  5

在此数据帧中,第零行和第五行是对称的,这意味着如果将第零行的整个AB列进行翻转,则它将与第五个。同样,第二行本身也是对称的。

我打算从原始数据框中删除这些行,从而使其“不对称”。具体计划如下:

  1. 如果具有较高索引的行与具有较低索引的行是对称的,请保留较低的行并删除较高的行。例如,从上面的数据框中,保留第0行并删除第五行。
  2. 如果一行与自己对称,则删除该行。例如,从上面的数据框中,删除第二行。

我的尝试是首先将四个列表压缩到一个元组列表中,通过简单的if语句删除对称的元组,解压缩它们,然后将它们合并回一个数据帧中。但是,事实证明这效率很低,因此无法用于大型数据帧。

如何有效地实现这一目标?我猜想有必要使用几种内置的pandas方法,但这似乎很复杂。

1 个答案:

答案 0 :(得分:1)

Namudon'tdie

尝试以下解决方案:

import pandas as pd
test = pd.DataFrame({('A', 'a'):[1,2,3,4,5], ('A', 'b'):[5,4,3,2,1], ('B', 'a'):[5,2,3,4,1], ('B','b'):[1,4,3,2,5]})

test['idx'] = test.index * 2  # adding auxiliary column 'idx' (all even)

test2 = test.iloc[:, [2,3,0,1,4]]   # creating flipped DF
test2.columns = test.columns  # fixing column names
test2['idx'] = test2.index * 2 + 1  # for flipped DF column 'idx' is all odd

df = pd.concat([test, test2])
df = df.sort_values (by='idx')
df = df.set_index('idx')
print(df)

     A     B   
     a  b  a  b
idx            
0    1  5  5  1
1    5  1  1  5
2    2  4  2  4
3    2  4  2  4
4    3  3  3  3
5    3  3  3  3
6    4  2  4  2
7    4  2  4  2
8    5  1  1  5
9    1  5  5  1

df = df.drop_duplicates()  # remove rows with duplicates 
df = df[df.index%2 == 0]  # remove rows with odd idx (flipped)
df = df.reset_index()[['A', 'B']] 
print(df)

   A     B   
   a  b  a  b
0  1  5  5  1
1  2  4  2  4
2  3  3  3  3
3  4  2  4  2

这个想法是用奇数索引创建翻转行,以便在重新索引后将它们放置在原始行的下面。然后删除重复项,使行的索引较低。为了进行清理,只需删除具有奇数索引的其余行。

请注意,第[3,3,3,3]行保留了。应该有一个单独的过滤器来处理自对称行。由于您对自对称的定义不清楚(其他行也具有一定程度的对称性),因此我将这一部分留给您。应该简单明了。