source

ValueError: 값의 길이가 인덱스의 길이와 일치하지 않습니다. | PandasDataFrame.unique()

factcode 2023. 9. 16. 09:56
반응형

ValueError: 값의 길이가 인덱스의 길이와 일치하지 않습니다. | PandasDataFrame.unique()

새로운 데이터셋을 구하거나 현재 데이터셋 열의 값을 고유 값으로 변경하려고 합니다.다음은 제가 얻고자 하는 것의 예입니다.

   A B
 -----
0| 1 1
1| 2 5
2| 1 5
3| 7 9
4| 7 9
5| 8 9

Wanted Result    Not Wanted Result
       A B              A B
     -----             -----
    0| 1 1           0| 1 1
    1| 2 5           1| 2 5
    2| 7 9           2| 
    3| 8             3| 7 9
                     4|
                     5| 8

지수는 별로 상관없는데 그게 문제인 것 같아요.지금까지 제 코드는 꽤 간단합니다. 하나는 새로운 데이터 프레임으로, 하나는 그렇지 않은 두 가지 접근법을 시도했습니다.

#With New DataFrame
def UniqueResults(dataframe):
    df = pd.DataFrame()
    for col in dataframe:
        S=pd.Series(dataframe[col].unique())
        df[col]=S.values
    return df

#Without new DataFrame
def UniqueResults(dataframe):
    for col in dataframe:
        dataframe[col]=dataframe[col].unique()
    return dataframe

두 번 다 오류가 납니다.

Length of Values does not match length of index

다른 길이의 numpy 배열 목록을 데이터 프레임에 할당하려고 할 때 오류가 발생하며 다음과 같이 재생할 수 있습니다.

4개 행으로 구성된 데이터 프레임:

df = pd.DataFrame({'A': [1,2,3,4]})

이제 두 요소의 목록/배열을 여기에 할당하려고 합니다.

df['B'] = [3,4]   # or df['B'] = np.array([3,4])

두 오류 모두 발생:

ValueError: 값의 길이가 인덱스의 길이와 일치하지 않습니다.

데이터 프레임에는 행이 4개 있지만 리스트와 배열에는 두 개의 요소만 있기 때문입니다.

해결 방법(주의 사항과 함께 사용): 목록/배열을 팬더 시리즈로 변환한 다음 할당을 수행하면 시리즈의 결측 지수가 NaN으로 채워집니다.

df['B'] = pd.Series([3,4])

df
#   A     B
#0  1   3.0
#1  2   4.0
#2  3   NaN          # NaN because the value at index 2 and 3 doesn't exist in the Series
#3  4   NaN

특정 문제의 경우, 인덱스나 열 간 값의 대응 관계에 신경 쓰지 않는 경우, 중복 항목을 삭제한 후 각 열에 대한 인덱스를 재설정할 수 있습니다.

df.apply(lambda col: col.drop_duplicates().reset_index(drop=True))

#   A     B
#0  1   1.0
#1  2   5.0
#2  7   9.0
#3  8   NaN

이 문제를 해결하는 한 가지 방법은 고유 값을 목록에 유지하고 사용하는 것입니다.itertools.zip_longest데이터를 변환하여 DataFrame 생성기로 전달하는 방법:

from itertools import zip_longest
def UniqueResults(dataframe):
    tmp = [dataframe[col].unique() for col in dataframe]
    return pd.DataFrame(zip_longest(*tmp), columns=dataframe.columns)

out = UniqueResults(df)

출력:

   A    B
0  1  1.0
1  2  5.0
2  7  9.0
3  8  NaN

적어도 작은 데이터 프레임의 경우에는 이보다 더 빠른 것 같습니다(예: OP의 샘플).

%timeit out = df.apply(lambda col: col.drop_duplicates().reset_index(drop=True))
1.27 ms ± 50.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit x = UniqueResults(df)
426 µs ± 24.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

또 다른 간단한 해결책은 OP가 제시한 해결책을 실행 가능한 것으로 만드는 것입니다.우리는 단지 각 칼럼의 독특한 가치를 팬더 시리즈에 담아내기만 하면 됩니다.

df1 = df.apply(lambda col: pd.Series(col.unique()))
df1

result

당신은 코드를 바꿀 수 있습니다.

def UniqueResults(dataframe):
   df = pd.DataFrame()
   for col in dataframe:
       S=dataframe[col].unique()
       df=pd.concat([df,S],axis=1)
   df.columns=dataframe.columns
   return df

`

언급URL : https://stackoverflow.com/questions/42382263/valueerror-length-of-values-does-not-match-length-of-index-pandas-dataframe-u

반응형