我有一个多索引数据框,看起来像这样:
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
在此数据帧中,第零行和第五行是对称的,这意味着如果将第零行的整个A
和B
列进行翻转,则它将与第五个。同样,第二行本身也是对称的。
我打算从原始数据框中删除这些行,从而使其“不对称”。具体计划如下:
我的尝试是首先将四个列表压缩到一个元组列表中,通过简单的if
语句删除对称的元组,解压缩它们,然后将它们合并回一个数据帧中。但是,事实证明这效率很低,因此无法用于大型数据帧。
如何有效地实现这一目标?我猜想有必要使用几种内置的pandas
方法,但这似乎很复杂。
答案 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]
行保留了。应该有一个单独的过滤器来处理自对称行。由于您对自对称的定义不清楚(其他行也具有一定程度的对称性),因此我将这一部分留给您。应该简单明了。