각 행의 함수로 행을 필터링하고 싶습니다. 예 :
def f(row):
return sin(row['velocity'])/np.prod(['masses']) > 5
df = pandas.DataFrame(...)
filtered = df[apply_to_all_rows(df, f)]
또는 더 복잡하고 인위적인 또 다른 예를 들어,
def g(row):
if row['col1'].method1() == 1:
val = row['col1'].method2() / row['col1'].method3(row['col3'], row['col4'])
else:
val = row['col2'].method5(row['col6'])
return np.sin(val)
df = pandas.DataFrame(...)
filtered = df[apply_to_all_rows(df, g)]
어떻게 할 수 있습니까?
답변
DataFrame.apply
주어진 축을 따라 함수를 적용하는를 사용하여이 작업을 수행 할 수 있습니다 .
In [3]: df = pandas.DataFrame(np.random.randn(5, 3), columns=['a', 'b', 'c'])
In [4]: df
Out[4]:
a b c
0 -0.001968 -1.877945 -1.515674
1 -0.540628 0.793913 -0.983315
2 -1.313574 1.946410 0.826350
3 0.015763 -0.267860 -2.228350
4 0.563111 1.195459 0.343168
In [6]: df[df.apply(lambda x: x['b'] > x['c'], axis=1)]
Out[6]:
a b c
1 -0.540628 0.793913 -0.983315
2 -1.313574 1.946410 0.826350
3 0.015763 -0.267860 -2.228350
4 0.563111 1.195459 0.343168
답변
다음과 같이 DataFrame이 있다고 가정합니다.
In [39]: df
Out[39]:
mass1 mass2 velocity
0 1.461711 -0.404452 0.722502
1 -2.169377 1.131037 0.232047
2 0.009450 -0.868753 0.598470
3 0.602463 0.299249 0.474564
4 -0.675339 -0.816702 0.799289
sin 및 DataFrame.prod를 사용하여 부울 마스크를 만들 수 있습니다.
In [40]: mask = (np.sin(df.velocity) / df.ix[:, 0:2].prod(axis=1)) > 0
In [41]: mask
Out[41]:
0 False
1 False
2 False
3 True
4 True
그런 다음 마스크를 사용하여 DataFrame에서 선택합니다.
In [42]: df[mask]
Out[42]:
mass1 mass2 velocity
3 0.602463 0.299249 0.474564
4 -0.675339 -0.816702 0.799289
답변
reduce=True
빈 DataFrame도 처리하도록 지정하십시오 .
import pandas as pd
t = pd.DataFrame(columns=['a', 'b'])
t[t.apply(lambda x: x['a'] > 1, axis=1, reduce=True)]
답변
나는 duckworthd의 대답 에 대해 언급 할 수 없지만 완벽하게 작동하지 않습니다. 데이터 프레임이 비어 있으면 충돌합니다.
df = pandas.DataFrame(columns=['a', 'b', 'c'])
df[df.apply(lambda x: x['b'] > x['c'], axis=1)]
출력 :
ValueError: Must pass DataFrame with boolean values only
{}는 확실히 유효한 부울 값 집합이기 때문에 나에게 판다의 버그처럼 보입니다. 해결책은 Roy Hyunjin Han의 답변을 참조하십시오 .
답변
내가 찾은 가장 좋은 방법 reduce=True
은 빈 df에 대한 오류를 피하기 위해 사용 하는 대신 (이 인수는 어쨌든 사용되지 않기 때문에) 필터를 적용하기 전에 df 크기> 0인지 확인하는 것입니다.
def my_filter(row):
if row.columnA == something:
return True
return False
if len(df.index) > 0:
df[df.apply(my_filter, axis=1)]
답변
loc
데이터 프레임 분할에 속성을 사용할 수 있습니다 .
문서 에
따르면 인수를 loc
가질 수 있습니다 callable function
.
In [3]: df = pandas.DataFrame(np.random.randn(5, 3), columns=['a', 'b', 'c'])
In [4]: df
Out[4]:
a b c
0 -0.001968 -1.877945 -1.515674
1 -0.540628 0.793913 -0.983315
2 -1.313574 1.946410 0.826350
3 0.015763 -0.267860 -2.228350
4 0.563111 1.195459 0.343168
# define lambda function
In [5]: myfilter = lambda x: x['b'] > x['c']
# use my lambda in loc
In [6]: df1 = df.loc[fif]
필터 기능 fif
을 다른 필터 기준과 결합하려는 경우
df1 = df.loc[fif].loc[(df.b >= 0.5)]