1

I have Pandas DataFrame that looks like this:

| Index | Value        |
|-------|--------------|
| 1     | [1, 12, 123] |
| 2     | [12, 123, 1] |
| 3     | [123, 12, 1] |

and I want to append third column with list of array elements lengths:

| Index | Value        | Expected_value |
|-------|--------------|----------------|
| 1     | [1, 12, 123] | [1, 2, 3]      |
| 2     | [12, 123, 1] | [2, 3, 1]      |
| 3     | [123, 12, 1] | [3, 2, 1]      |

I've tried to use python lambda function and mapping little bit like this:

dataframe["Expected_value"] = dataframe.value.map(lambda x: len(str(x)))

but instead of list I got sum of those lengths:

| Index | Value        | Expected_value |
|-------|--------------|----------------|
| 1     | [1, 12, 123] | 6              |
| 2     | [12, 123, 1] | 6              |
| 3     | [123, 12, 1] | 6              |
pkolawa
  • 653
  • 6
  • 17

2 Answers2

3

You can use list comprehension with map:

dataframe["Expected_value"] = dataframe.Value.map(lambda x: [len(str(y)) for y in x])

Or nested list comprehension:

dataframe["Expected_value"] = [[len(str(y)) for y in x] for x in dataframe.Value]

There is also possible use alternative for get lengths of integers:

import math
dataframe["Expected_value"] = [[int(math.log10(y))+1 for y in x] for x in dataframe.Value]

print (dataframe)
   Index         Value Expected_value
0      1  [1, 12, 123]      [1, 2, 3]
1      2  [12, 123, 1]      [2, 3, 1]
2      3  [123, 12, 1]      [3, 2, 1]
jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252
1

Use a list comprehension:

[[len(str(y)) for y in x] for x in df['Value'].tolist()]
# [[1, 2, 3], [2, 3, 1], [3, 2, 1]]

df['Expected_value'] = [[len(str(y)) for y in x] for x in df['Value'].tolist()]
df

   Index         Value Expected_value
0      1  [1, 12, 123]      [1, 2, 3]
1      2  [12, 123, 1]      [2, 3, 1]
2      3  [123, 12, 1]      [3, 2, 1]

If you need to handle missing data,

def foo(x):
    try:
       return [len(str(y)) for y in x]
    except TypeError:
        return np.nan

df['Expected_value'] = [foo(x) for x in df['Value'].tolist()]
df

   Index         Value Expected_value
0      1  [1, 12, 123]      [1, 2, 3]
1      2  [12, 123, 1]      [2, 3, 1]
2      3  [123, 12, 1]      [3, 2, 1]

It is probably the best in terms of performance when dealing with object type data. More reading at For loops with pandas - When should I care?.


Another solution with pd.DataFrame, applymap and agg:

pd.DataFrame(df['Value'].tolist()).astype(str).applymap(len).agg(list, axis=1)

0    [1, 2, 3]
1    [2, 3, 1]
2    [3, 2, 1]
dtype: object
Erfan
  • 40,971
  • 8
  • 66
  • 78
cs95
  • 379,657
  • 97
  • 704
  • 746