简体   繁体   中英

pandas - apply replace function with condition row-wise

Starting with this dataframe df :

     0     1     2
02  en    it  None
03  en  None  None
01  nl    en   fil

There are some missing values. I'm trying to apply a replace function row-wise, eg in pseudocode:

def replace(x):
    if 'fil' and 'nl' in row:
        x = ''

I know that I can do someting like:

df.apply(f, axis=1)

with a function f defined like:

def f(x):
    if x[0] == 'nl' and x[2] == 'fil':
        x[0] = ''
    return x

obtaining:

     0     1     2
02  en    it  None
03  en  None  None
01        en   fil

but a priori I don't know the actual positions of the strings through the columns, so I have to search with something like the isin method, but row-wise.

EDIT: every string can appear anywhere throughout the columns.

You can do something like this:

In [111]:
def func(x):
    return x.isin(['fil']).any() &  x.isin(['nl']).any()
df.loc[df.apply(func, axis=1)] = df.replace('nl','')
df

Out[111]:
    0     1     2
2  en    it  None
3  en  None  None
1        en   fil

So the function will return True if both values are present in the row in any position:

In [107]:
df.apply(func, axis=1)

Out[107]:
2    False
3    False
1     True
dtype: bool

Boolean Indexing and Text Comparison in Pandas

You could create boolean indexing based on string comparisons like this

df['0'].str.contains('nl') & df['2'].str.contains('fil')

or since you updated that the columns could change:

df.isin(['fil']).any(axis=1) & df.isin(['nl']).any(axis=1)

Here is the test case:

import pandas as pd
from cStringIO import StringIO

text_file = '''
     0     1     2
02  en    it  None
03  en  None  None
01  nl    en   fil
'''

# Read in tabular data
df = pd.read_table(StringIO(text_file), sep='\s+')
print 'Original Data:'
print df
print

# Create boolean index based on text comparison
boolIndx = df.isin(['nl']).any(axis=1) & df.isin(['fil']).any(axis=1)
print 'Example Boolean index:'
print boolIndx
print

# Replace string based on boolean assignment   
df.loc[boolIndx] = df.loc[boolIndx].replace('nl', '')
print 'Filtered Data:'
print df
print

Original Data:
    0     1     2
2  en    it  None
3  en  None  None
1  nl    en   fil

Example Boolean index:
2    False
3    False
1     True
dtype: bool

Filtered Data:
    0     1     2
2  en    it  None
3  en  None  None
1        en   fil

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM