我有一个多列的pandas数据框。这些列中的2个应该相等,但在单独的行中,而第二列中的第三列应该相等。
例如,给定数据帧df [A,B,C],找到row_x和row_y使得:
(df.iloc[x, A] == df.iloc[y, B]) and (df.iloc[x, B] == df.iloc[y, A]) and (df.iloc[x, C] == df.iloc[y, C])
是否有比遍历框架以获取具有交换列的行更好的方法?
A = [30,31]+list(range(2,8,1))+[38,39]
B = range(10,0,-1)
C = [True, False, True, False, False, False, True, False, True, False]
df = pd.DataFrame({'A': A, 'B': B, 'C': C})
Out[]: df
A B C
0 30 10 True
1 31 9 False
2 2 8 True
3 3 7 False
4 4 6 False
5 5 5 False
6 6 4 True
7 7 3 False
8 38 2 True
9 39 1 False
Required output:
A B C
3 3 7 False
5 5 5 False
7 7 3 False
只有第3、5和7行满足上述条件。我将进一步删除第5行,因为我对A列= B列的行不感兴趣。请注意,第4行和第6行在A和B列中也交换了值,但在C列中交换了值。
答案 0 :(得分:2)
使用GroupBy
根据列C
进行分组。请使用GroupBy.apply和Series.isin
检查两个系列的通用值(A
和B
),
那么您可以将DataFrame.unstack与DataFrame.any结合使用来执行Boolean indexing:
new_df=df[df.groupby('C').apply(lambda x: x['A'].isin(x['B'])&x['B'].isin(x['A'])).unstack().any()]
print(new_df)
A B C
3 3 7 False
5 5 5 False
7 7 3 False
针对您的评论:
df['A'].isin(df['B'])
0 False
1 False
2 True
3 True
4 True
5 True
6 True
7 True
8 False
9 False
Name: A, dtype: bool
df['A']==df['B']
0 False
1 False
2 False
3 False
4 False
5 True
6 False
7 False
8 False
9 False
dtype: bool
答案 1 :(得分:1)
关键是将数据框与其自身合并,将B
列与A
列匹配:
df = df.merge(df.rename({'B': 'A', 'A': 'AfromB', 'C': 'CfromB'}, axis=1), how='left')
df = df[(df['B'] == df['AfromB']) & (df['C'] == df['CfromB'])].drop(['AfromB', 'CfromB'], axis=1)