복붙노트

[PYTHON] 파이썬 팬더 중복 열 제거

PYTHON

파이썬 팬더 중복 열 제거

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

다음을 통해 중복 된 열이있는 텍스트 파일을 읽습니다.

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

팬더 멍청한 것에 대해 유감스럽게 생각합니다. 모든 제안을 부탁드립니다.

추가 세부 사항

팬더 버전 : 0.9.0 Python 버전 : 2.7.3 윈도우 7 (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

해결법

  1. ==============================

    1.이미 고유 한 열 이름을 알고있는 것 같습니다. 그렇다면 df = df [ 'Time', 'Time Relative', 'N2']가 작동합니다.

    이미 고유 한 열 이름을 알고있는 것 같습니다. 그렇다면 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 
    
  2. ==============================

    2.위의 모든 것은 불필요하게 무겁고 지루한 방법으로 보입니다 - 문제에 대한 한 가지 해결책이 있습니다. 이는 일부 컬럼 이름이 중복되어이를 제거하고자하는 경우에 적용됩니다.

    위의 모든 것은 불필요하게 무겁고 지루한 방법으로 보입니다 - 문제에 대한 한 가지 해결책이 있습니다. 이는 일부 컬럼 이름이 중복되어이를 제거하고자하는 경우에 적용됩니다.

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

    데이터 프레임의 열이 [ 'alpha', 'beta', 'alpha']라고 가정합니다.

    df.columns.duplicated ()는 부울 배열을 반환합니다. 각 열에 대해 True 또는 False입니다. False이면 열 이름이 해당 지점까지 고유합니다. True이면 열 이름이 먼저 복제됩니다. 예를 들어 주어진 예제를 사용하면 반환 된 값은 [False, False, True]가됩니다.

    Pandas는 부울 값을 사용하여 색인을 생성하여 True 값만 선택하도록 허용합니다. 비 중복 열을 유지하고자하므로 위의 부울 배열을 대칭 이동해야합니다 (예 : [True, True, False] = ~ [False, False, True]).

    마지막으로 df.loc [:, [True, True, False]]는 앞서 언급 한 인덱싱 기능을 사용하여 중복되지 않는 열만 선택합니다.

    참고 : 위 항목은 열 이름이 아닌 열 이름 만 확인합니다.

  3. ==============================

    3.필자가 잘못 생각하지 않는다면, 다음은 트랜스 포션 솔루션의 메모리 문제없이 비슷한 칼럼의 첫 번째 컬럼을 유지하면서 @kalu의 함수보다 줄이 적은 질문을한다.

    필자가 잘못 생각하지 않는다면, 다음은 트랜스 포션 솔루션의 메모리 문제없이 비슷한 칼럼의 첫 번째 컬럼을 유지하면서 @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)
    
  4. ==============================

    4.조 변경은 대형 DataFrames에서는 비효율적입니다. 다음은 대안입니다.

    조 변경은 대형 DataFrames에서는 비효율적입니다. 다음은 대안입니다.

    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)
    

    편집하다

    다른 값처럼 nans를 처리하는 메모리 효율적인 버전 :

    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
    
  5. from https://stackoverflow.com/questions/14984119/python-pandas-remove-duplicate-columns by cc-by-sa and MIT license