복붙노트

[PYTHON] Pandas 데이터 프레임에서 특이점 검색 및 제외

PYTHON

Pandas 데이터 프레임에서 특이점 검색 및 제외

몇 가지 열이있는 판다 데이터 프레임이 있습니다.

이제 특정 행이 특정 열 값을 기반으로하는 특이점이라는 것을 알고 있습니다.

예를 들어, 열 - 'Vol'는 12.xx 주변의 모든 값과 4000 인 하나의 값을가집니다.

이제 Vol Column이있는 행을 제외하고 싶습니다.

그래서 본질적으로 필자는 특정 열의 값이 평균에서 3 표준 편차 이내 인 모든 행을 선택하도록 필터를 배치해야합니다.

이것을 달성하는 우아한 방법은 무엇입니까?

해결법

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

    1.numpy.array에서와 같이 부울 식 색인을 사용하십시오.

    numpy.array에서와 같이 부울 식 색인을 사용하십시오.

    df = pd.DataFrame({'Data':np.random.normal(size=200)})
    # example dataset of normally distributed data. 
    
    df[np.abs(df.Data-df.Data.mean()) <= (3*df.Data.std())]
    # keep only the ones that are within +3 to -3 standard deviations in the column 'Data'.
    
    df[~(np.abs(df.Data-df.Data.mean()) > (3*df.Data.std()))]
    # or if you prefer the other way around
    

    시리즈의 경우도 비슷합니다.

    S = pd.Series(np.random.normal(size=200))
    S[~((S-S.mean()).abs() > 3*S.std())]
    
  2. ==============================

    2.데이터 프레임에 여러 개의 열이 있고 적어도 하나의 열에 이상 값이있는 모든 행을 제거하려는 경우 다음 식은 한 번에 수행 할 수 있습니다.

    데이터 프레임에 여러 개의 열이 있고 적어도 하나의 열에 이상 값이있는 모든 행을 제거하려는 경우 다음 식은 한 번에 수행 할 수 있습니다.

    df = pd.DataFrame(np.random.randn(100, 3))
    
    from scipy import stats
    df[(np.abs(stats.zscore(df)) < 3).all(axis=1)]
    
  3. ==============================

    3.각 데이터 프레임 열에 대해 다음을 사용하여 quantile을 얻을 수 있습니다.

    각 데이터 프레임 열에 대해 다음을 사용하여 quantile을 얻을 수 있습니다.

    q = df["col"].quantile(0.99)
    

    다음으로 필터링 :

    df[df["col"] < q]
    
  4. ==============================

    4.이 답변은 @tanemaki가 제공하는 것과 비슷하지만 scipy stats 대신 lambda 표현식을 사용합니다.

    이 답변은 @tanemaki가 제공하는 것과 비슷하지만 scipy stats 대신 lambda 표현식을 사용합니다.

    df = pd.DataFrame(np.random.randn(100, 3), columns=list('ABC'))
    
    df[df.apply(lambda x: np.abs(x - x.mean()) / x.std() < 3).all(axis=1)]
    

    하나의 열 (예 : 'B')만이 세 표준 편차 이내 인 DataFrame을 필터링하려면 다음과 같이하십시오.

    df[((df.B - df.B.mean()) / df.B.std()).abs() < 3]
    
  5. ==============================

    5.

    #------------------------------------------------------------------------------
    # accept a dataframe, remove outliers, return cleaned data in a new dataframe
    # see http://www.itl.nist.gov/div898/handbook/prc/section1/prc16.htm
    #------------------------------------------------------------------------------
    def remove_outlier(df_in, col_name):
        q1 = df_in[col_name].quantile(0.25)
        q3 = df_in[col_name].quantile(0.75)
        iqr = q3-q1 #Interquartile range
        fence_low  = q1-1.5*iqr
        fence_high = q3+1.5*iqr
        df_out = df_in.loc[(df_in[col_name] > fence_low) & (df_in[col_name] < fence_high)]
        return df_out
    
  6. ==============================

    6.scipy.stats에는 제거 된 값의 랭킹과 도입 된 비율에 따라 단일 행에서 이상 값을 잘라 내기위한 trim1 () 및 trimboth () 메소드가 있습니다.

    scipy.stats에는 제거 된 값의 랭킹과 도입 된 비율에 따라 단일 행에서 이상 값을 잘라 내기위한 trim1 () 및 trimboth () 메소드가 있습니다.

  7. ==============================

    7.또 다른 옵션은 이상 치의 영향을 완화 할 수 있도록 데이터를 변환하는 것입니다. 데이터를 winsorizing하여이 작업을 수행 할 수 있습니다.

    또 다른 옵션은 이상 치의 영향을 완화 할 수 있도록 데이터를 변환하는 것입니다. 데이터를 winsorizing하여이 작업을 수행 할 수 있습니다.

    import pandas as pd
    from scipy.stats import mstats
    %matplotlib inline
    
    test_data = pd.Series(range(30))
    test_data.plot()
    

    # Truncate values to the 5th and 95th percentiles
    transformed_test_data = pd.Series(mstats.winsorize(test_data, limits=[0.05, 0.05])) 
    transformed_test_data.plot()
    

  8. ==============================

    8.메쏘드 체이닝이 마음에 들면, 다음과 같이 모든 숫자 열에 대한 부울 조건을 얻을 수 있습니다 :

    메쏘드 체이닝이 마음에 들면, 다음과 같이 모든 숫자 열에 대한 부울 조건을 얻을 수 있습니다 :

    df.sub(df.mean()).div(df.std()).abs().lt(3)
    

    각 열의 각 값은 평균보다 3 표준 편차가 작은 지 여부에 따라 True / False로 변환됩니다.

  9. ==============================

    9.데이터와 두 그룹의 전체 예제는 다음과 같습니다.

    데이터와 두 그룹의 전체 예제는 다음과 같습니다.

    수입 :

    from StringIO import StringIO
    import pandas as pd
    #pandas config
    pd.set_option('display.max_rows', 20)
    

    2 그룹의 데이터 예제 : G1 : 그룹 1. G2 : 그룹 2 :

    TESTDATA = StringIO("""G1;G2;Value
    1;A;1.6
    1;A;5.1
    1;A;7.1
    1;A;8.1
    
    1;B;21.1
    1;B;22.1
    1;B;24.1
    1;B;30.6
    
    2;A;40.6
    2;A;51.1
    2;A;52.1
    2;A;60.6
    
    2;B;80.1
    2;B;70.6
    2;B;90.6
    2;B;85.1
    """)
    

    pandas 데이터 프레임으로 텍스트 데이터 읽기 :

    df = pd.read_csv(TESTDATA, sep=";")
    

    표준 편차를 사용하여 특이점을 정의하십시오.

    stds = 1.0
    outliers = df[['G1', 'G2', 'Value']].groupby(['G1','G2']).transform(
               lambda group: (group - group.mean()).abs().div(group.std())) > stds
    

    필터링 된 데이터 값과 이상 치를 정의하십시오 :

    dfv = df[outliers.Value == False]
    dfo = df[outliers.Value == True]
    

    결과 인쇄 :

    print '\n'*5, 'All values with decimal 1 are non-outliers. In the other hand, all values with 6 in the decimal are.'
    print '\nDef DATA:\n%s\n\nFiltred Values with %s stds:\n%s\n\nOutliers:\n%s' %(df, stds, dfv, dfo)
    
  10. ==============================

    10.이상 치를 떨어 뜨리는 내 기능

    이상 치를 떨어 뜨리는 내 기능

    def drop_outliers(df, field_name):
        distance = 1.5 * (np.percentile(df[field_name], 75) - np.percentile(df[field_name], 25))
        df.drop(df[df[field_name] > distance + np.percentile(df[field_name], 75)].index, inplace=True)
        df.drop(df[df[field_name] < np.percentile(df[field_name], 25) - distance].index, inplace=True)
    
  11. from https://stackoverflow.com/questions/23199796/detect-and-exclude-outliers-in-pandas-dataframe by cc-by-sa and MIT license