使多索引数据帧非对称

2024-05-16 01:05:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个多索引数据帧,大致如下所示:

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

在此数据帧中,第0行和第5行是对称的,即如果第0行的整个A列和B列被翻转,则第0行和第5行将变得与第5行相同。类似地,第二行与自身对称

我计划从我的原始数据帧中删除这些行,从而使其“非对称”。具体方案如下:

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

我的尝试是首先将四个列表压缩成一个元组列表,通过一个简单的if-语句删除对称元组,解压缩它们,然后将它们合并回一个数据帧。然而,这被证明是低效的,使得它无法对大型数据帧进行缩放

如何以有效的方式实现这一点?我想使用几种内置的pandas方法是必要的,但它似乎相当复杂


Tags: 数据testimportdataframepandas列表output原始数据
1条回答
网友
1楼 · 发布于 2024-05-16 01:05:09

纳木冬蒂

尝试以下解决方案:

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]保持不变。应该有一个单独的过滤器来处理自对称行。由于您对自对称的定义不清楚(其他行也有一定程度的对称性),所以我将这部分留给您。应该是直截了当的

相关问题 更多 >