복붙노트

[PYTHON] dict의 값을 사용하여 pandas 데이터 프레임 필터링

PYTHON

dict의 값을 사용하여 pandas 데이터 프레임 필터링

필자는 dict로 데이터 프레임을 필터링해야하는데, 키는 열 이름이고 값은 필터링 할 값입니다.

filter_v = {'A':1, 'B':0, 'C':'This is right'}
# this would be the normal approach
df[(df['A'] == 1) & (df['B'] ==0)& (df['C'] == 'This is right')]

하지만 나는 뭔가를하고 싶다.

for column, value in filter_v.items():
    df[df[column] == value]

그러나 이것은 한 번에 하나의 값으로 여러 번 데이터 프레임을 필터링하며 동시에 모든 필터를 적용하지 않습니다. 프로그래밍 방식으로이를 수행 할 수있는 방법이 있습니까?

편집 : 예 :

df1 = pd.DataFrame({'A':[1,0,1,1, np.nan], 'B':[1,1,1,0,1], 'C':['right','right','wrong','right', 'right'],'D':[1,2,2,3,4]})
filter_v = {'A':1, 'B':0, 'C':'right'}
df1.loc[df1[filter_v.keys()].isin(filter_v.values()).all(axis=1), :]

주는

    A   B   C   D
0   1   1   right   1
1   0   1   right   2
3   1   0   right   3

예상 된 결과는

    A   B   C   D
3   1   0   right   3

마지막 하나만 선택해야합니다.

해결법

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

    1.IIUC, 당신은 이런 식으로 할 수 있어야합니다 :

    IIUC, 당신은 이런 식으로 할 수 있어야합니다 :

    >>> df1.loc[(df1[list(filter_v)] == pd.Series(filter_v)).all(axis=1)]
       A  B      C  D
    3  1  0  right  3
    

    이것은 비교할 시리즈를 만들어서 작동합니다 :

    >>> pd.Series(filter_v)
    A        1
    B        0
    C    right
    dtype: object
    

    df1의 해당 부분 선택 :

    >>> df1[list(filter_v)]
        A      C  B
    0   1  right  1
    1   0  right  1
    2   1  wrong  1
    3   1  right  0
    4 NaN  right  1
    

    일치하는 위치 찾기 :

    >>> df1[list(filter_v)] == pd.Series(filter_v)
           A      B      C
    0   True  False   True
    1  False  False   True
    2   True  False  False
    3   True   True   True
    4  False  False   True
    

    일치하는 위치 찾기 :

    >>> (df1[list(filter_v)] == pd.Series(filter_v)).all(axis=1)
    0    False
    1    False
    2    False
    3     True
    4    False
    dtype: bool
    

    그리고 마지막으로 이것을 df1에 색인하기 위해 :

    >>> df1.loc[(df1[list(filter_v)] == pd.Series(filter_v)).all(axis=1)]
       A  B      C  D
    3  1  0  right  3
    
  2. ==============================

    2.다음과 같이 할 수 있습니다.

    다음과 같이 할 수 있습니다.

    df.loc[df[filter_v.keys()].isin(filter_v.values()).all(axis=1), :]
    

    최신 정보:

    값이 열에서 동일하면 다음과 같이 할 수 있습니다.

    # Create your filtering function:
    
    def filter_dict(df, dic):
        return df[df[dic.keys()].apply(
                lambda x: x.equals(pd.Series(dic.values(), index=x.index, name=x.name)), asix=1)]
    
    # Use it on your DataFrame:
    
    filter_dict(df1, filter_v)
    

    어느 결과 :

       A  B      C  D
    3  1  0  right  3            
    

    자주하는 일이라면 DataFrame을 패치하여이 필터에 쉽게 액세스 할 수 있습니다.

    pd.DataFrame.filter_dict_ = filter_dict
    

    그런 다음이 필터를 다음과 같이 사용하십시오.

    df1.filter_dict_(filter_v)
    

    같은 결과가 나올 겁니다.

    그러나 그것을 분명히하는 올바른 방법은 아닙니다. 나는 DSM의 접근법을 사용할 것이다.

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

    3.다른 방법이 있습니다.

    다른 방법이 있습니다.

    filterSeries = pd.Series(np.ones(df.shape[0],dtype=bool))
    for column, value in filter_v.items():
        filterSeries = ((df[column] == value) & filterSeries)
    

    이것은 준다 :

    >>> df[filterSeries]
       A  B      C  D
    3  1  0  right  3 
    
  4. from https://stackoverflow.com/questions/34157811/filter-a-pandas-dataframe-using-values-from-a-dict by cc-by-sa and MIT license