Boon
Boon

Reputation: 75

How do i change multiple columns of specific rows in pandas dataframe with custom functions?

I would like to edit the following dataframe with custom function defined, my dataframe returned empty for rows that passed through the custom function

df
      field      value1            value2          value3
0    target     ['list']       ['123','length']     'abc'
1    random      [32.67]           [47.00]          'bcd'
2    target      ['word']           [105]           'efg'
3    target2   ["key":"123"]    ["key":"333"]       'xyz'

my custom function

def f(field, value1, value2):
    if field == 'target':
        value1 = [{item} for item in value1]
        value2 = [{item} for item in value2]
    elif field == 'target2':
        value1 = [{item.values()} for item in value1]
        value2 = [{item.values()} for item in value2]
    return pd.Series([value1, value2])

so i did the following

mask = df['field'].isin(['target','target2'])
df.loc[mask,['value1','value2']] = df[mask].apply(lamba row: f(row['field'], row['value1'], row['value2'], axis=1)

my result is the following, which caused my targetted row to return as NaN

df
      field      value1       value2     value3
0    target       NaN          NaN        'abc'
1    random      [32.67]      [47.00]     'bcd'
2    target       NaN          NaN        'efg' 
3    target2      NaN          NaN        'xyz' 

my Expected result

df
      field      value1               value2              value3
0    target     [{'list'}]       [{'123'},{'length'}]     'abc'
1    random      [32.67]             [47.00]              'bcd'
2    target      [{'word'}]          [{105}]              'efg'
3    target2    [{"123"}]            [{"333"}]            'xyz'

Thank you!

Upvotes: 0

Views: 654

Answers (1)

Ynjxsjmh
Ynjxsjmh

Reputation: 30032

You need set the index of returned Series to matched the columns

def f(field, value1, value2):
    if field == 'target':
        value1 = [{item} for item in value1]
        value2 = [{item} for item in value2]
    elif field == 'target2':
        value1 = [{item.values()} for item in value1]
        value2 = [{item.values()} for item in value2]
    s = pd.Series([value1, value2], index=['value1', 'value2']) # <--- changes here
    return s

mask = df['field'].isin(['target','target2'])
df.loc[mask, ['value1','value2']] = df[mask].apply(lambda row: f(row['field'], row['value1'], row['value2']), axis=1)
print(df)

     field     value1             value2 value3
0   target   [{list}]  [{123}, {length}]  'abc'
1   random    [32.67]             [47.0]  'bcd'
2   target   [{word}]            [{105}]  'efg'
3  target2  [{(123)}]          [{(333)}]  'xyz'

Upvotes: 2

Related Questions