source

비단뱀 판다는 중복된 기둥을 제거한다

lovecheck 2022. 12. 28. 21:50
반응형

비단뱀 판다는 중복된 기둥을 제거한다

데이터 프레임에서 중복 열을 제거하는 가장 쉬운 방법은 무엇입니까?

열이 중복된 텍스트 파일을 읽고 있습니다.

import pandas as pd

df=pd.read_table(fname)

열 이름은 다음과 같습니다.

Time, Time Relative, N2, Time, Time Relative, H2, etc...

모든 시간 및 시간 상대 열에 동일한 데이터가 포함되어 있습니다.나는 다음을 원한다:

Time, Time Relative, N2, H2

드롭, 삭제 등의 모든 시도:

df=df.T.drop_duplicates().T

고유하게 평가된 인덱스 오류가 발생합니다.

Reindexing only valid with uniquely valued index objects

팬더 누브라서 미안해.어떤 제안이라도 해주시면 감사하겠습니다.


기타 상세

버전
Python ™ : 2.7.3
7 ®7
2. 완료)(Pythonxy 2.7.3.0 경유)

데이터 파일(주: 실제 파일에서는 열은 탭으로 구분됩니다.여기서는 4개의 공백으로 구분됩니다).

Time    Time Relative [s]    N2[%]    Time    Time Relative [s]    H2[ppm]
2/12/2013 9:20:55 AM    6.177    9.99268e+001    2/12/2013 9:20:55 AM    6.177    3.216293e-005    
2/12/2013 9:21:06 AM    17.689    9.99296e+001    2/12/2013 9:21:06 AM    17.689    3.841667e-005    
2/12/2013 9:21:18 AM    29.186    9.992954e+001    2/12/2013 9:21:18 AM    29.186    3.880365e-005    
... etc ...
2/12/2013 2:12:44 PM    17515.269    9.991756+001    2/12/2013 2:12:44 PM    17515.269    2.800279e-005    
2/12/2013 2:12:55 PM    17526.769    9.991754e+001    2/12/2013 2:12:55 PM    17526.769    2.880386e-005
2/12/2013 2:13:07 PM    17538.273    9.991797e+001    2/12/2013 2:13:07 PM    17538.273    3.131447e-005

다음은 중복된 열 이름을 기준으로 열을 제거하는 한 줄 솔루션입니다.

df = df.loc[:,~df.columns.duplicated()].copy()

구조:

이 이이음음음음음음음음음음음음고고고고고고고 suppose suppose suppose 。['alpha','beta','alpha']

df.columns.duplicated() 배열 배열')을 합니다.True ★★★★★★★★★★★★★★★★★」False각 컬럼에 대해. False하고, 이 열은해해 it it it it it it이다.True그러면 열 이름이 이전에 중복됩니다.예를 들어, 주어진 예를 사용하면 반환되는 값은 다음과 같습니다.[False,False,True].

Pandas할 수 .부울값으로 부울값만 할 수 있습니다.이 값을 사용하면,True되지 않은 하려면 위의 부울 합니다( 부울 배열을 뒤집어야 합니다).[True, True, False] = ~[False,False,True])

ㅇㅇㅇㅇㅇ.df.loc[:,[True,True,False]]는 앞에서 설명한 인덱싱 기능을 사용하여 복제되지 않은 열만 선택합니다.

★★★★★★.copy()는 데이터 프레임을 (복사하기 위해) 나중에 기존 데이터 프레임을 변경하려고 하는 에러가 발생하는 것을 방지합니다.

주의: 위에서는 열 이름만 확인하고 열 값은 확인하지 않습니다.

중복 인덱스를 제거하려면 다음과 같이 하십시오.

충분히 비슷하므로 인덱스에서 동일한 작업을 수행합니다.

df = df.loc[~df.index.duplicated(),:].copy()

바꾸지 않고 값을 확인하여 중복 항목을 제거하는 방법

df = df.loc[:,~df.apply(lambda x: x.duplicated(),axis=1).all()].copy()

이것에 의해, 이행의 문제가 회피됩니다.빨라요?아뇨, 작동하나요?그래, 이거 입어봐

# create a large(ish) dataframe
ldf = pd.DataFrame(np.random.randint(0,100,size= (736334,1312))) 


#to see size in gigs
#ldf.memory_usage().sum()/1e9 #it's about 3 gigs

# duplicate a column
ldf.loc[:,'dup'] = ldf.loc[:,101]

# take out duplicated columns by values
ldf = ldf.loc[:,~ldf.apply(lambda x: x.duplicated(),axis=1).all()].copy()

고유한 열 이름을 이미 알고 계신 것 같네요. 약면면면 df = df['Time', 'Time Relative', 'N2']효과가 있을 거야

그렇지 않으면 솔루션이 작동합니다.

In [101]: vals = np.random.randint(0,20, (4,3))
          vals
Out[101]:
array([[ 3, 13,  0],
       [ 1, 15, 14],
       [14, 19, 14],
       [19,  5,  1]])

In [106]: df = pd.DataFrame(np.hstack([vals, vals]), columns=['Time', 'H1', 'N2', 'Time Relative', 'N2', 'Time'] )
          df
Out[106]:
   Time  H1  N2  Time Relative  N2  Time
0     3  13   0              3  13     0
1     1  15  14              1  15    14
2    14  19  14             14  19    14
3    19   5   1             19   5     1

In [107]: df.T.drop_duplicates().T
Out[107]:
   Time  H1  N2
0     3  13   0
1     1  15  14
2    14  19  14
3    19   5   1

데이터를 망치고 있는 특정 데이터가 있을 수 있습니다.데이터에 대해 더 자세히 알려주시면 더 많은 도움을 드릴 수 있습니다.

편집: Andy가 말했듯이 중복된 열 제목에 문제가 있을 수 있습니다.

샘플 테이블 파일 'dummy.csv'의 경우 다음과 같이 작성했습니다.

Time    H1  N2  Time    N2  Time Relative
3   13  13  3   13  0
1   15  15  1   15  14
14  19  19  14  19  14
19  5   5   19  5   1

를 사용합니다.read_table 작동합니다.

In [151]: df2 = pd.read_table('dummy.csv')
          df2
Out[151]:
         Time  H1  N2  Time.1  N2.1  Time Relative
      0     3  13  13       3    13              0
      1     1  15  15       1    15             14
      2    14  19  19      14    19             14
      3    19   5   5      19     5              1
In [152]: df2.T.drop_duplicates().T
Out[152]:
             Time  H1  Time Relative
          0     3  13              0
          1     1  15             14
          2    14  19             14
          3    19   5              1  

사용 중인 버전에서 허용되지 않는 경우 솔루션을 함께 해킹하여 고유한 솔루션을 만들 수 있습니다.

In [169]: df2 = pd.read_table('dummy.csv', header=None)
          df2
Out[169]:
              0   1   2     3   4              5
        0  Time  H1  N2  Time  N2  Time Relative
        1     3  13  13     3  13              0
        2     1  15  15     1  15             14
        3    14  19  19    14  19             14
        4    19   5   5    19   5              1
In [171]: from collections import defaultdict
          col_counts = defaultdict(int)
          col_ix = df2.first_valid_index()
In [172]: cols = []
          for col in df2.ix[col_ix]:
              cnt = col_counts[col]
              col_counts[col] += 1
              suf = '_' + str(cnt) if cnt else ''
              cols.append(col + suf)
          cols
Out[172]:
          ['Time', 'H1', 'N2', 'Time_1', 'N2_1', 'Time Relative']
In [174]: df2.columns = cols
          df2 = df2.drop([col_ix])
In [177]: df2
Out[177]:
          Time  H1  N2 Time_1 N2_1 Time Relative
        1    3  13  13      3   13             0
        2    1  15  15      1   15            14
        3   14  19  19     14   19            14
        4   19   5   5     19    5             1
In [178]: df2.T.drop_duplicates().T
Out[178]:
          Time  H1 Time Relative
        1    3  13             0
        2    1  15            14
        3   14  19            14
        4   19   5             1 

대규모 데이터 프레임에서는 전환이 비효율적입니다.대체 방법은 다음과 같습니다.

def duplicate_columns(frame):
    groups = frame.columns.to_series().groupby(frame.dtypes).groups
    dups = []
    for t, v in groups.items():
        dcols = frame[v].to_dict(orient="list")

        vs = dcols.values()
        ks = dcols.keys()
        lvs = len(vs)

        for i in range(lvs):
            for j in range(i+1,lvs):
                if vs[i] == vs[j]: 
                    dups.append(ks[i])
                    break

    return dups       

다음과 같이 사용합니다.

dups = duplicate_columns(frame)
frame = frame.drop(dups, axis=1)

편집

nan을 다른 값과 동일하게 취급하는 메모리 효율 버전:

from pandas.core.common import array_equivalent

def duplicate_columns(frame):
    groups = frame.columns.to_series().groupby(frame.dtypes).groups
    dups = []

    for t, v in groups.items():

        cs = frame[v].columns
        vs = frame[v]
        lcs = len(cs)

        for i in range(lcs):
            ia = vs.iloc[:,i].values
            for j in range(i+1, lcs):
                ja = vs.iloc[:,j].values
                if array_equivalent(ia, ja):
                    dups.append(cs[i])
                    break

    return dups

내가 틀리지 않았다면, 다음은 transpose 솔루션의 메모리 문제 없이 @kalu 함수보다 적은 행으로 동일한 이름의 열 중 첫 번째 열을 유지하도록 요청받은 내용을 수행합니다.

Cols = list(df.columns)
for i,item in enumerate(df.columns):
    if item in df.columns[:i]: Cols[i] = "toDROP"
df.columns = Cols
df = df.drop("toDROP",1)

올바른 길을 가고 있었던 것 같아요.찾으시는 원라이너는 다음과 같습니다.

df.reset_index().T.drop_duplicates().T

, 「」를 생성하는 의 예는 .Reindexing only valid with uniquely valued index objects할 수 것이 는 어렵습니다를 들어, 원래 를 복원하는 한 경우 과 같습니다원래 인덱스 복원이 중요한 경우 다음을 수행합니다.

original_index = df.index.names
df.reset_index().T.drop_duplicates().reset_index(original_index).T

Gene Burinsky의 답변(선택한 답변 작성 시)은 각 중복된 컬럼의 첫 번째 컬럼을 유지합니다.마지막을 유지하려면:

df=df.loc[:, ~df.columns[::-1].duplicated()[::-1]]

최신 판다를 사용한 @kalu의 답변 업데이트:

def find_duplicated_columns(df):
    dupes = []

    columns = df.columns

    for i in range(len(columns)):
        col1 = df.iloc[:, i]
        for j in range(i + 1, len(columns)):
            col2 = df.iloc[:, j]
            # break early if dtypes aren't the same (helps deal with
            # categorical dtypes)
            if col1.dtype is not col2.dtype:
                break
            # otherwise compare values
            if col1.equals(col2):
                dupes.append(columns[i])
                break

    return dupes

@Gene Burinsky의 답변은 훌륭하지만, 재할당된 df가 원래 df의 복사 또는 표시일 수 있다는 점에서 잠재적인 문제가 있습니다.에 붙는 , 즉 ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴdf['newcol'] = 1 SettingWithCopy에러가 발생할 수 있습니다(https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#why-does-assignment-fail-when-using-chained-indexing)).다음 솔루션을 통해 이 문제를 방지할 수 있습니다.

duplicate_cols = df.columns[df.columns.duplicated()]
df.drop(columns=duplicate_cols, inplace=True)

저는 첫 번째 답변에서 제공한 하나의 라이너가 잘 작동하는 문제에 부딪혔습니다.그러나 컬럼의 두 번째 복사본이 모든 데이터를 포함하는 추가적인 문제가 있었습니다.첫 번째 복사본은 그렇지 않았다.

해결책은 부정 연산자를 전환하여 1개의 데이터 프레임을 분할하여 2개의 데이터 프레임을 생성하는 것이었습니다.프레임이 2개의 join 스테이트먼트를 했습니다.lsuffix이렇게 하면 데이터 없이 열을 참조하고 삭제할 수 있습니다.

(E)

2021년 3월 갱신

@CircArgs의 다음 글은 내가 여기서 설명한 것을 달성하기 위한 간결한 한 줄의 글을 제공했을지도 모른다.

첫 번째 단계:- 첫 번째 행을 읽습니다.즉, 모든 열을 읽고 모든 중복 열을 제거합니다.

두 번째 단계: 마지막으로 해당 열만 읽습니다.

cols = pd.read_csv("file.csv", header=None, nrows=1).iloc[0].drop_duplicates()
df = pd.read_csv("file.csv", usecols=cols)

다음 방법에서는 dupe 열을 식별하고 데이터 프레임을 처음 구축하는 과정에서 무엇이 잘못되었는지 확인합니다.

dupes = pd.DataFrame(df.columns)
dupes[dupes.duplicated()]

Python의 Pandars Data Frame 컬럼에서 중복된 값을 찾는 방법을 찾는 사람이 있을 경우를 대비해서 이 솔루션을 생각해냈습니다.

def get_dup_columns(m):
    '''
    This will check every column in data frame 
    and verify if you have duplicated columns.
    can help whenever you are cleaning big data sets of 50+ columns 
    and clean up a little  bit for you
    The result will be a list of tuples showing what columns are duplicates
    for example
    (column A, Column C)
    That means that column A is duplicated with column C
    more info go to https://wanatux.com
    '''
    headers_list = [x for x in m.columns]
    duplicate_col2 = []
    y = 0
    while y <= len(headers_list)-1:
        for x in range(1,len(headers_list)-1):
            if m[headers_list[y]].equals(m[headers_list[x]]) == False:        
                continue
            else:
                duplicate_col2.append((headers_list[y],headers_list[x]))
        headers_list.pop(0)  
    return duplicate_col2

정의를 다음과 같이 지정할 수 있습니다.

duplicate_col = get_dup_columns(pd_excel)

다음과 같은 결과가 나타납니다.

 [('column a', 'column k'),
 ('column a', 'column r'),
 ('column h', 'column m'),
 ('column k', 'column r')]

나는 왜 진 부린스키의 대답이 나에게 효과가 없었는지 모르겠다.열이 중복된 동일한 원본 데이터 프레임을 가져오고 있었습니다.회피책은 ndarray에서 선택을 강제하고 데이터 프레임을 되돌리는 것이었습니다.

df = pd.DataFrame(df.values[:,~df.columns.duplicated()], columns=df.columns[~df.columns.duplicated()])

단순 열별 비교는 중복 을 값별로 확인하는 가장 효율적인 방법입니다.다음은 예를 제시하겠습니다.

import numpy as np
import pandas as pd
from itertools import combinations as combi

df = pd.DataFrame(np.random.uniform(0,1, (100,4)), columns=['a','b','c','d'])
df['a'] = df['d'].copy()  # column 'a' is equal to column 'd'

# to keep the first
dupli_cols = [cc[1] for cc in combi(df.columns, r=2) if (df[cc[0]] == df[cc[1]]).all()]

# to keep the last
dupli_cols = [cc[0] for cc in combi(df.columns, r=2) if (df[cc[0]] == df[cc[1]]).all()]
            
df = df.drop(columns=dupli_cols)

중복된 열을 값별로 빠르고 쉽게 드롭할 수 있습니다.

df = df.T.drop_duplicates().t

상세정보: Panda Data Frame drop_duplicates 매뉴얼.

언급URL : https://stackoverflow.com/questions/14984119/python-pandas-remove-duplicate-columns

반응형