programing

Panda "동일하게 레이블이 지정된 DataFrame 개체만 비교할 수 있습니다" 오류

skycolor 2023. 7. 21. 21:28
반응형

Panda "동일하게 레이블이 지정된 DataFrame 개체만 비교할 수 있습니다" 오류

Pandas를 사용하여 두 개의 데이터 프레임(uat, prod)에 로드된 두 개의 파일의 출력을 비교하고 있습니다. ...

uat = uat[['Customer Number','Product']]
prod = prod[['Customer Number','Product']]
print uat['Customer Number'] == prod['Customer Number']
print uat['Product'] == prod['Product']
print uat == prod

The first two match exactly:
74357    True
74356    True
Name: Customer Number, dtype: bool
74357    True
74356    True
Name: Product, dtype: bool

세 번째 인쇄의 경우 레이블이 동일한 DataFrame 개체만 비교할 수 있습니다.처음 두 개가 잘 비교됐다면, 세 번째는 뭐가 문제야?

감사해요.

다음은 이를 보여주는 작은 예입니다(Panda 0.19가 적용될 때까지 시리즈가 아닌 데이터 프레임에만 적용됨).

In [1]: df1 = pd.DataFrame([[1, 2], [3, 4]])

In [2]: df2 = pd.DataFrame([[3, 4], [1, 2]], index=[1, 0])

In [3]: df1 == df2
Exception: Can only compare identically-labeled DataFrame objects

한 가지 해결책은 먼저 인덱스를 정렬하는 것입니다(참고: 일부 함수의 경우 정렬된 인덱스가 필요함).

In [4]: df2.sort_index(inplace=True)

In [5]: df1 == df2
Out[5]: 
      0     1
0  True  True
1  True  True

참고:==또한 열 순서에 민감하므로 를 사용해야 할 수도 있습니다.sort_index(axis=1):

In [11]: df1.sort_index().sort_index(axis=1) == df2.sort_index().sort_index(axis=1)
Out[11]: 
      0     1
0  True  True
1  True  True

참고: 정렬 후 인덱스/열에 동일한 레이블이 지정되지 않은 경우에도 계속 증가할 수 있습니다.

비교할 필요가 없는 경우 인덱스 열을 삭제할 수도 있습니다.

print(df1.reset_index(drop=True) == df2.reset_index(drop=True))

저는 유닛 테스트에서 다음과 같은 동일한 기법을 사용했습니다.

from pandas.util.testing import assert_frame_equal

assert_frame_equal(actual.reset_index(drop=True), expected.reset_index(drop=True))

이 질문이 제기되었을 때 판다에는 평등을 테스트하는 다른 기능이 없었지만, 얼마 전에 추가되었습니다.

다음과 같이 사용합니다.

df1.equals(df2)

에 대한 몇 가지 차이점==다음과 같습니다.

  • 질문에 설명된 오류를 이해하지 못합니다.
  • 단순 부울을 반환합니다.
  • 동일한 위치의 NaN 값이 동일한 것으로 간주됩니다.
  • 한 2개의 데이터 프레임을 .dtype동일한 것으로 간주하려면 이 스택 오버플로 질문을 참조하십시오.


@paperskilltree에서 지적했듯이 답변 색인 정렬은 중요합니다.제공되는 솔루션 외에도 데이터 프레임을 비교하기 전에 데이터 프레임의 인덱스를 정렬하는 방법이 있습니다.df1은 것은그일 입니다.df1.sort_index(inplace=True).

두 개의 데이터 프레임을 비교할 때 첫 번째 데이터 프레임의 레코드 수가 두 번째 데이터 프레임의 레코드 수와 일치하는지 확인해야 합니다.이 예에서는 두 개의 데이터 프레임 각각에 4개의 제품과 4개의 가격으로 4개의 레코드가 있었습니다.

예를 들어, 데이터 프레임 중 하나에 5개의 제품이 있고 다른 데이터 프레임에는 4개의 제품이 있는데 비교를 실행하려고 하면 다음 오류가 발생합니다.

ValueError: 레이블이 동일한 Series 객체만 비교할 수 있습니다.

이것은 효과가 있을 것입니다.

import pandas as pd
import numpy as np

firstProductSet = {'Product1': ['Computer','Phone','Printer','Desk'],
                   'Price1': [1200,800,200,350]
                   }
df1 = pd.DataFrame(firstProductSet,columns= ['Product1', 'Price1'])


secondProductSet = {'Product2': ['Computer','Phone','Printer','Desk'],
                    'Price2': [900,800,300,350]
                    }
df2 = pd.DataFrame(secondProductSet,columns= ['Product2', 'Price2'])


df1['Price2'] = df2['Price2'] #add the Price2 column from df2 to df1

df1['pricesMatch?'] = np.where(df1['Price1'] == df2['Price2'], 'True', 'False')  #create new column in df1 to check if prices match
df1['priceDiff?'] = np.where(df1['Price1'] == df2['Price2'], 0, df1['Price1'] - df2['Price2']) #create new column in df1 for price diff 
print (df1)

https://datatofish.com/compare-values-dataframes/ 의 예

플라잉 더치맨의 대답훌륭하지만 틀렸습니다: 그것은 사용합니다, 그것은 돌아올 것입니다.False당신의 경우에는대신, 를 사용하고 싶을 경우 이 반환됩니다.True.

는 것 같습니다.DataFrame.equals데이터 프레임의 인덱스를 무시하는 동안DataFrame.eq에서는 정렬에 데이터 프레임의 인덱스를 사용한 다음 정렬된 값을 비교합니다.이것은 판다의 중심적인 고차를 인용하는 기회입니다.

여기 명심해야 할 기본 원칙이 있습니다. 데이터 정렬은 본질적입니다.레이블과 데이터 간의 연결은 사용자가 명시적으로 수행하지 않는 한 끊어지지 않습니다.

다음 예제에서 볼 수 있듯이, 데이터 정렬은 명시적으로 요청하지 않는 한 중단되거나 시행되지 않습니다.그래서 우리는 세 가지 다른 상황을 가지고 있습니다.

  1. 정렬과 관련하여 명시적인 지침이 제공되지 않았습니다.==아카DataFrame.__eq__,

   In [1]: import pandas as pd
   In [2]: df1 = pd.DataFrame(index=[0, 1, 2], data={'col1':list('abc')})
   In [3]: df2 = pd.DataFrame(index=[2, 0, 1], data={'col1':list('cab')})
   In [4]: df1 == df2
   ---------------------------------------------------------------------------
   ...
   ValueError: Can only compare identically-labeled DataFrame objects

  1. 선형이 명백하게 손상되었습니다.DataFrame.equals,DataFrame.values,DataFrame.reset_index(),
    In [5]: df1.equals(df2)
    Out[5]: False

    In [9]: df1.values == df2.values
    Out[9]: 
    array([[False],
           [False],
           [False]])

    In [10]: (df1.values == df2.values).all().all()
    Out[10]: False

  1. 정렬이 명시적으로 적용됩니다.DataFrame.eq,DataFrame.sort_index(),

    In [6]: df1.eq(df2)
    Out[6]: 
       col1
    0  True
    1  True
    2  True

    In [8]: df1.eq(df2).all().all()
    Out[8]: True
    

제 대답은 판다 버전입니다.1.0.3.

추신: 데이터 프레임을 자신과 비교하면 자동으로 정렬되므로 정렬에 대한 내용을 잊어버릴 수 있습니다.이것은 위의 모든 방법들이 당신에게 제공한다는 것을 의미합니까?True결측값이 없는 데이터 프레임에만 해당됩니다.그러나 데이터 프레임에 결측값이 포함되어 있으면,equals()수확량True그리고 모든 다른 방법들은 양보합니다.False그 이유는equals()두 개를 치료NaN동등하게, 이것은 매우 이례적입니다(관습에 따르면,np.nan == np.nan이라False).

여기에서는 이 오류를 처리하는 방법에 대한 완전한 예를 보여 줍니다.0이 있는 행을 추가했습니다.csv 또는 다른 소스에서 데이터 프레임을 가져올 수 있습니다.

import pandas as pd
import numpy as np


# df1 with 9 rows
df1 = pd.DataFrame({'Name':['John','Mike','Smith','Wale','Marry','Tom','Menda','Bolt','Yuswa',],
    'Age':[23,45,12,34,27,44,28,39,40]})

# df2 with 8 rows
df2 = pd.DataFrame({'Name':['John','Mike','Wale','Marry','Tom','Menda','Bolt','Yuswa',],
    'Age':[25,45,14,34,26,44,29,42]})


# get lengths of df1 and df2
df1_len = len(df1)
df2_len = len(df2)


diff = df1_len - df2_len

rows_to_be_added1 = rows_to_be_added2 = 0
# rows_to_be_added1 = np.zeros(diff)

if diff < 0:
    rows_to_be_added1 = abs(diff)
else:
    rows_to_be_added2 = diff
    
# add empty rows to df1
if rows_to_be_added1 > 0:
    df1 = df1.append(pd.DataFrame(np.zeros((rows_to_be_added1,len(df1.columns))),columns=df1.columns))

# add empty rows to df2
if rows_to_be_added2 > 0:
    df2 = df2.append(pd.DataFrame(np.zeros((rows_to_be_added2,len(df2.columns))),columns=df2.columns))

# at this point we have two dataframes with the same number of rows, and maybe different indexes
# drop the indexes of both, so we can compare the dataframes and other operations like update etc.
df2.reset_index(drop=True, inplace=True)
df1.reset_index(drop=True, inplace=True)

# add a new column to df1
df1['New_age'] = None

# compare the Age column of df1 and df2, and update the New_age column of df1 with the Age column of df2 if they match, else None
df1['New_age'] = np.where(df1['Age'] == df2['Age'], df2['Age'], None)

# drop rows where Name is 0.0
df2 = df2.drop(df2[df2['Name'] == 0.0].index)

# now we don't get the error ValueError: Can only compare identically-labeled Series objects

이 경우 오류가 발생하는 위치를 발견했습니다.

문제는 열 이름 목록이 실수로 다른 목록에 포함되었다는 것입니다.

다음 예를 고려합니다.

column_names=['warrior','eat','ok','monkeys']

df_good = pd.DataFrame(np.ones(shape=(6,4)),columns=column_names)
df_good['ok'] < df_good['monkeys']

>>> 0    False
    1    False
    2    False
    3    False
    4    False
    5    False

df_bad = pd.DataFrame(np.ones(shape=(6,4)),columns=[column_names])
df_bad ['ok'] < df_bad ['monkeys']

>>> ValueError: Can only compare identically-labeled DataFrame objects

그리고 문제는 나쁜 데이터 프레임과 좋은 데이터 프레임을 시각적으로 구별할 수 없다는 것입니다.

제 경우에는 데이터 프레임을 만들 때 파라메타 열을 직접 씁니다. 한 SQL 쿼리의 데이터가 이름을 포함하고 다른 SQL 쿼리에는 포함되지 않았기 때문입니다.

언급URL : https://stackoverflow.com/questions/18548370/pandas-can-only-compare-identically-labeled-dataframe-objects-error

반응형