2017-11-02 4 views
0

나는 이런 팬더 dataframe 있습니다. 하지만 partial string과 일치하는 if 함수를 약간 조정해야합니다.파이썬 함수 부분 문자열 일치

여러 가지 조합을 시도했지만 작동하지 않을 수 있습니다.

("'str' object has no attribute 'str'", 'occurred at index 0')

시도 Iv'e 기능은 다음과 같습니다 :

def somenewfunction (row): 
    if row['a'].str.contains('foo')==True and row['b'] == 'bar': 
     return 'yes' 
    return 'no' 

답변

1

부울 마스크를 사용 contains 다음 numpy.where :

m = df['a'].str.contains('foo') & (df['b'] == 'bar') 
print (m) 
0  True 
1 False 
2 False 
dtype: bool 

df['new'] = np.where(m, 'yes', 'no') 
print (df) 
     a  b c new 
0  foo  bar baz yes 
1  bar  foo baz no 
2 foobar barfoo baz no 

또는 필요하다면 무조건 나는 다음과 같은 오류가 발생합니다 하위 문자열의 열 b을 확인하십시오.

m = df['a'].str.contains('foo') & df['b'].str.contains('bar') 
df['new'] = np.where(m, 'yes', 'no') 
print (df) 
     a  b c new 
0  foo  bar baz yes 
1  bar  foo baz no 
2 foobar barfoo baz yes 

필요 사용자 정의 기능, 무슨 slowier 큰 DataFrame에서 할 필요가있는 경우 :

def somefunction (row): 
    if 'foo' in row['a'] and row['b'] == 'bar': 
     return 'yes' 
    return 'no' 

print (df.apply(somefunction, axis=1)) 
0 yes 
1  no 
2  no 
dtype: object 

def somefunction (row): 
    if 'foo' in row['a'] and 'bar' in row['b']: 
     return 'yes' 
    return 'no' 

print (df.apply(somefunction, axis=1)) 
0 yes 
1  no 
2 yes 
dtype: object 

타이밍 :

df = pd.concat([df]*1000).reset_index(drop=True) 

def somefunction (row): 
    if 'foo' in row['a'] and row['b'] == 'bar': 
     return 'yes' 
    return 'no' 

In [269]: %timeit df['new'] = df.apply(somefunction, axis=1) 
10 loops, best of 3: 60.7 ms per loop 

In [270]: %timeit df['new1'] = np.where(df['a'].str.contains('foo') & (df['b'] == 'bar'), 'yes', 'no') 
100 loops, best of 3: 3.25 ms per loop 

df = pd.concat([df]*10000).reset_index(drop=True) 

def somefunction (row): 
    if 'foo' in row['a'] and row['b'] == 'bar': 
     return 'yes' 
    return 'no' 

In [272]: %timeit df['new'] = df.apply(somefunction, axis=1) 
1 loop, best of 3: 614 ms per loop 

In [273]: %timeit df['new1'] = np.where(df['a'].str.contains('foo') & (df['b'] == 'bar'), 'yes', 'no') 
10 loops, best of 3: 23.5 ms per loop 
+0

아 네. 제가 놓친 행렬입니다. 감사! – Kvothe

1

귀하의 예외는

if row['a'].str.contains('foo')==True 

제거 쓰기는 사실에서 아마도 '.str'

if row['a'].contains('foo')==True