У меня есть два фрейма данных с одинаковым индексом, но разными именами столбцов. Количество столбцов одинаковое. Я хочу проверить, индексировать по индексу, 1) имеют ли они одинаковый набор значений независимо от порядка столбцов и 2) имеют ли они одинаковый набор значений относительно порядка столбцов.
ind = ['aaa', 'bbb', 'ccc']
df1 = pd.DataFrame({'old1': ['A','A','A'], 'old2': ['B','B','B'], 'old3': ['C','C','C']}, index=ind)
df2 = pd.DataFrame({'new1': ['A','A','A'], 'new2': ['B','C','B'], 'new3': ['C','B','D']}, index=ind)
Это выход, который мне нужен.
OpX OpY
-------------
aaa True True
bbb False True
ccc False False
Может ли кто-нибудь помочь мне с OpX и OpY?
Использование tuple
и set
: сохранить порядок или кортеж и изменить порядок с помощью set
s1=df1.apply(tuple,1)==df2.apply(tuple,1)
s2=df1.apply(set,1)==df2.apply(set,1)
pd.concat([s1,s2],1)
Out[746]:
0 1
aaa True True
bbb False True
ccc False False
Поскольку cs95 упоминается, у приложения есть проблема здесь
s=np.equal(df1.values,df2.values).all(1)
t=np.equal(np.sort(df1.values,1),np.sort(df2.values,1)).all(1)
pd.DataFrame(np.column_stack([s,t]),index=df1.index)
Out[754]:
0 1
aaa True True
bbb False True
ccc False False
По пункту 2):
(df1.values == df2.values).all(axis=1)
Это проверяет поэлементное равенство фреймов данных и дает True
, когда все записи в строке равны.
Для элемента 1 сначала отсортируйте значения по каждой строке:
import numpy as np
(np.sort(df1.values, axis=1) == np.sort(df2.values, axis=1)).all(axis=1)
Постройте новый DataFrame
и проверьте равенство:
df3 = pd.DataFrame(index=ind)
df3['OpX'] = (df1.values == df2.values).all(1)
df3['OpY'] = (df1.apply(np.sort, axis=1).values == df2.apply(np.sort, axis=1).values).all(1)
print(df3)
Выход:
OpX OpY
aaa True True
bbb False True
ccc False False
Вот решение, которое является производительным и должно масштабироваться. Во-первых, выровняйте кадры данных по индексу, чтобы их было легко сравнивать.
df3 = df2.set_axis(df1.columns, axis=1, inplace=False)
df4, df5 = df1.align(df3)
Для req 1 просто вызовите DataFrame.equals
(или просто используйте ==
op):
u = (df4 == df5).all(axis=1)
u
aaa True
bbb False
ccc False
dtype: bool
Req 2 немного сложнее, отсортируйте их по первой оси, а затем сравните.
v = pd.Series((np.sort(df4) == np.sort(df5)).all(axis=1), index=u.index)
v
aaa True
bbb True
ccc False
dtype: bool
Объедините результаты,
pd.concat([u, v], axis=1, keys=['X', 'Y'])
X Y
aaa True True
bbb False True
ccc False False