programing

panda: 연산자 체인으로 DataFrame 행을 필터링합니다.

kingscode 2022. 10. 2. 21:57
반응형

panda: 연산자 체인으로 DataFrame 행을 필터링합니다.

에서의 pandas 체인연산자 체인)으로할 수 .groupby,aggregate,apply은, 의 괄호 하는 것 뿐입니다.

df_filtered = df[df['column'] == value]

이지 않습니다.왜냐하면 제가 입니다.df값을 필터링하기 전에 변수를 필터링합니다.음음음음 음음음?

df_filtered = df.mask(lambda x: x['column'] == value)

뭘 원하는지 잘 모르겠고, 마지막 줄의 코드도 도움이 안 되지만, 어쨌든:

"체인" 필터링은 부울 인덱스의 기준을 "체인"하여 수행됩니다.

In [96]: df
Out[96]:
   A  B  C  D
a  1  4  9  1
b  4  5  0  2
c  5  5  1  0
d  1  3  9  6

In [99]: df[(df.A == 1) & (df.D == 6)]
Out[99]:
   A  B  C  D
d  1  3  9  6

메서드를 체인하는 경우 자체 마스크 메서드를 추가하여 사용할 수 있습니다.

In [90]: def mask(df, key, value):
   ....:     return df[df[key] == value]
   ....:

In [92]: pandas.DataFrame.mask = mask

In [93]: df = pandas.DataFrame(np.random.randint(0, 10, (4,4)), index=list('abcd'), columns=list('ABCD'))

In [95]: df.ix['d','A'] = df.ix['a', 'A']

In [96]: df
Out[96]:
   A  B  C  D
a  1  4  9  1
b  4  5  0  2
c  5  5  1  0
d  1  3  9  6

In [97]: df.mask('A', 1)
Out[97]:
   A  B  C  D
a  1  4  9  1
d  1  3  9  6

In [98]: df.mask('A', 1).mask('D', 6)
Out[98]:
   A  B  C  D
d  1  3  9  6

Panda 쿼리를 사용하여 필터를 연결할 수 있습니다.

df = pd.DataFrame(np.random.randn(30, 3), columns=['a','b','c'])
df_filtered = df.query('a > 0').query('0 < b < 2')

필터는 단일 쿼리로 결합할 수도 있습니다.

df_filtered = df.query('a > 0 and 0 < b < 2')

@lodagro의 답변은 훌륭합니다.마스크 기능을 다음과 같이 일반화하여 확장합니다.

def mask(df, f):
  return df[f(df)]

그런 다음 다음과 같은 작업을 수행할 수 있습니다.

df.mask(lambda x: x[0] < 0).mask(lambda x: x[1] > 0)

버전 0.18.1 이후로는.loc방법람다 함수와 함께 매우 유연한 체인 가능 필터를 만들 수 있습니다.

import numpy as np
import pandas as pd

df = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))
df.loc[lambda df: df.A == 80]  # equivalent to df[df.A == 80] but chainable

df.sort_values('A').loc[lambda df: df.A > 80].loc[lambda df: df.B > df.A]

하는 에는 필터링을..loc.

판다는 Wouter Overmeire의 대답에 대한 두 가지 대안을 제시하는데, 이는 무시될 필요가 없다.는 ★★★★★★★★★★★★★★★★★..loc[.] 콜 가능과

df_filtered = df.loc[lambda x: x['column'] == value]

하나는 른른 the the the the the the.pipe()의 같이

df_filtered = df.pipe(lambda x: x.loc[x['column'] == value])

추가 예시로 이것을 제안합니다.이는 https://stackoverflow.com/a/28159296/과 같은 답변입니다.

이 투고를 유용하게 하기 위해 다른 편집을 추가하겠습니다.

pandas.DataFrame.query
query정확히 이런 목적으로 만들어졌어요. 프레임에 대해 해 보겠습니다.df

import pandas as pd
import numpy as np

np.random.seed([3,1415])
df = pd.DataFrame(
    np.random.randint(10, size=(10, 5)),
    columns=list('ABCDE')
)

df

   A  B  C  D  E
0  0  2  7  3  8
1  7  0  6  8  6
2  0  2  0  4  9
3  7  3  2  4  3
4  3  6  7  7  4
5  5  3  7  5  9
6  8  7  6  4  7
7  6  2  6  6  5
8  2  8  7  5  8
9  4  7  6  1  5

용용 let let let let let let 를 사용합시다query D > B

df.query('D > B')

   A  B  C  D  E
0  0  2  7  3  8
1  7  0  6  8  6
2  0  2  0  4  9
3  7  3  2  4  3
4  3  6  7  7  4
5  5  3  7  5  9
7  6  2  6  6  5

우리가 묶는 것

df.query('D > B').query('C > B')
# equivalent to
# df.query('D > B and C > B')
# but defeats the purpose of demonstrating chaining

   A  B  C  D  E
0  0  2  7  3  8
1  7  0  6  8  6
4  3  6  7  7  4
5  5  3  7  5  9
7  6  2  6  6  5

제 답변은 다른 답변과 비슷합니다.새로운 기능을 만들고 싶지 않다면 판다들이 이미 정의한 기능을 사용할 수 있습니다.파이프 방법을 사용합니다.

df.pipe(lambda d: d[d['column'] == value])

수술 조건에 기준을 결합하고 싶다는 것 외에는 같은 질문이 있었습니다.Wouter Overmeire에 의해 주어진 형식은 기준을 AND 조건으로 결합하여 두 조건을 모두 충족해야 합니다.

In [96]: df
Out[96]:
   A  B  C  D
a  1  4  9  1
b  4  5  0  2
c  5  5  1  0
d  1  3  9  6

In [99]: df[(df.A == 1) & (df.D == 6)]
Out[99]:
   A  B  C  D
d  1  3  9  6

하지만 제가 찾은 건, 각각의 조건을(... == True)을 결합하면 OR 중 됩니다.

df[((df.A==1) == True) | ((df.D==6) == True)]

싶어요.loc행뿐만 아니라 열 및 체인 작동의 몇 가지 장점을 기준으로 필터링합니다.

아래 코드는 값을 기준으로 행을 필터링할 수 있습니다.

df_filtered = df.loc[df['column'] == value]

조금 수정하면 열을 필터링할 수도 있습니다.

df_filtered = df.loc[df['column'] == value, ['year', 'column']]

그럼 왜 연쇄 방식이 필요한 거죠?정답은 조작이 많으면 읽기 쉽다는 것입니다.예를들면,

res =  df\
    .loc[df['station']=='USA', ['TEMP', 'RF']]\
    .groupby('year')\
    .agg(np.nanmean)

일반적인 부울 마스크와 범용 마스크를 모두 적용하려면 파일에서 다음을 처킹한 후 다음과 같이 모든 마스크를 할당할 수 있습니다.

pd.DataFrame = apply_masks()

사용방법:

A = pd.DataFrame(np.random.randn(4, 4), columns=["A", "B", "C", "D"])
A.le_mask("A", 0.7).ge_mask("B", 0.2)... (May be repeated as necessary

다소 해킹적이긴 하지만 필터에 따라 데이터 세트를 지속적으로 잘라내고 변경할 경우 좀 더 깔끔하게 만들 수 있습니다.gen_mask 함수에는 위의 Daniel Velkov에서 개조된 범용 필터가 있으며, 람다 함수와 함께 사용하거나 원하는 경우 사용할 수 있습니다.

저장할 파일(masks.py 사용):

import pandas as pd

def eq_mask(df, key, value):
    return df[df[key] == value]

def ge_mask(df, key, value):
    return df[df[key] >= value]

def gt_mask(df, key, value):
    return df[df[key] > value]

def le_mask(df, key, value):
    return df[df[key] <= value]

def lt_mask(df, key, value):
    return df[df[key] < value]

def ne_mask(df, key, value):
    return df[df[key] != value]

def gen_mask(df, f):
    return df[f(df)]

def apply_masks():

    pd.DataFrame.eq_mask = eq_mask
    pd.DataFrame.ge_mask = ge_mask
    pd.DataFrame.gt_mask = gt_mask
    pd.DataFrame.le_mask = le_mask
    pd.DataFrame.lt_mask = lt_mask
    pd.DataFrame.ne_mask = ne_mask
    pd.DataFrame.gen_mask = gen_mask

    return pd.DataFrame

if __name__ == '__main__':
    pass

이 솔루션은 구현에 있어서는 좀 더 까다롭지만, 사용법에 관해서는 훨씬 깔끔하고, 다른 솔루션보다 확실히 일반적입니다.

https://github.com/toobaz/generic_utils/blob/master/generic_utils/pandas/where.py

전체 보고서를 다운로드할 필요는 없습니다. 파일을 저장하고

from where import where as W

충분할 겁니다.그런 다음 다음과 같이 사용합니다.

df = pd.DataFrame([[1, 2, True],
                   [3, 4, False], 
                   [5, 7, True]],
                  index=range(3), columns=['a', 'b', 'c'])
# On specific column:
print(df.loc[W['a'] > 2])
print(df.loc[-W['a'] == W['b']])
print(df.loc[~W['c']])
# On entire - or subset of a - DataFrame:
print(df.loc[W.sum(axis=1) > 3])
print(df.loc[W[['a', 'b']].diff(axis=1)['b'] > 1])

조금 덜 어리석은 사용 예를 다음에 나타냅니다.

data = pd.read_csv('ugly_db.csv').loc[~(W == '$null$').any(axis=1)]

참고로 부울콜을 사용하는 경우에도

df.loc[W['cond1']].loc[W['cond2']]

보다 훨씬 효율적일 수 있다

df.loc[W['cond1'] & W['cond2']]

평가하기 때문이다.cond2어디에서만cond1True.

부인: 나는 이것을 본 적이 없기 때문에 다른 곳에서 이 대답을 처음 했다.

이것은 할당이 필요하기 때문에 매력적이지 않습니다.df값을 필터링하기 전에 변수를 필터링합니다.

df[df["column_name"] != 5].groupby("other_column_name")

효과가 있는 것 같습니다.이것들은,[]오퍼레이터도 마찬가지입니다.아마 당신이 질문을 한 이후로 그들이 그것을 추가했을 것이다.

분석 가능한 데이터를 서브셋할 때는 두 가지 작업을 수행해야 합니다.

  • 야단맞다
  • 컬럼을 취득하다

판다들은 이것들 각각을 하는 많은 방법들과 과 기둥들을 얻는 데 도움을 주는 기술들을 가지고 있다.새로운 팬더 사용자들에게는 선택의 폭이 매우 넓기 때문에 혼란스러울 수 있다.

iloc, loc, 대괄호, 쿼리, isin, np.where, 마스크 등을 사용합니까?

메서드 체인

데이터 논쟁 시 방법 체인은 훌륭한 작업 방법입니다.R에서는 간단한 방법을 사용합니다.select() you(열과 너)filter()snowledge.snowledge.

그래서 우리가 판다들을 단순하게 하고 싶다면 왜 팬더들을 사용하지 않는가?filter() 및 컬럼의 경우query() 을 반환하기 부울 할 필요가 .따라서 부울 인덱싱을 추가.df[ ]반환값을 반올림합니다.

그럼 어떻게 생겼을까요?

df.filter(['col1', 'col2', 'col3']).query("col1 == 'sometext'")

다른 해서 사용할 수 .groupby,dropna(),sort_values(),reset_index()기타 등등.

'일관'을 filter()과 칼럼을 query()행을 가져오려면 잠시 후에 코드를 다시 읽어야 합니다.

필터는 행을 선택할 수 있습니까?

, 만, 로는 「」입니다.query()을 벌이다filter()컬럼을 가져옵니다. 굳이 하지 .axis=파라미터를 지정합니다.

쿼리()

query는 query()로 할 수 .and/or &/| 연산자를 사용할 도 있습니다.> , < , >= , <=, ==, !=Python's in. Python의 인.

@my_list를 사용하여 조회할 목록을 전달할 수 있습니다.

쿼리를 사용하여 행을 가져오는 몇 가지 예

df.query('A > B')

df.query('a not in b')

df.query("series == '2206'")

df.query("col1 == @mylist")

df.query('Salary_in_1000 >= 100 & Age < 60 & FT_Team.str.startswith("S").values')

필터()

필터는 으로 괄호를 사용하는 .df[] ★★★★★★★★★★★★★★★★★」df[[]]라벨을 사용하여 열을 선택합니다.하지만 괄호 표기법보다 더 많은 것을 합니다.

에 「」가 있습니다.like=하면 이름의을 쉽게 할 수 .

df.filter(like='partial_name',)

필터에는 선택에 도움이 되는 regex도 있습니다.

df.filter(regex='reg_string')

따라서 이러한 작업 방식을 요약하면 인덱싱/슬라이싱을 사용하려는 경우 iloc을 사용하는 것이 좋습니다.그러나 이는 확실한 작업 방식인 것 같으며 워크플로우와 코드를 단순화할 수 있습니다.

논리적 작업에 numpy 라이브러리를 활용할 수도 있습니다.꽤 빠르네요.

df[np.logical_and(df['A'] == 1 ,df['B'] == 6)]

인덱스를 인덱스로 할 수 .DataFrame.xs()이것은 다재다능하지 . 이것은 다재다능하지 않습니다.query하지만 상황에 따라서는 도움이 될 수도 있습니다.

import pandas as pd
import numpy as np

np.random.seed([3,1415])
df = pd.DataFrame(
    np.random.randint(3, size=(10, 5)),
    columns=list('ABCDE')
)

df
# Out[55]: 
#    A  B  C  D  E
# 0  0  2  2  2  2
# 1  1  1  2  0  2
# 2  0  2  0  0  2
# 3  0  2  2  0  1
# 4  0  1  1  2  0
# 5  0  0  0  1  2
# 6  1  0  1  1  1
# 7  0  0  2  0  2
# 8  2  2  2  2  2
# 9  1  2  0  2  1

df.set_index(['A', 'D']).xs([0, 2]).reset_index()
# Out[57]: 
#    A  D  B  C  E
# 0  0  2  2  2  2
# 1  0  2  1  1  0

언급URL : https://stackoverflow.com/questions/11869910/pandas-filter-rows-of-dataframe-with-operator-chaining

반응형