1

I'm trying to use a cell value as the slice for a string in a new column. For example, if I create this table.

data = pd.DataFrame(data = {'Name':['This is a title'], 'Number':[-5]})

               Name Number
0   This is a title     -5

And create a new column like so:

data['Test'] = data.Name.str[:data.Number.item()]

It'll create the new column, as expected:

               Name Number       Test
0   This is a title     -5  This is a 

The issue occurs when I have more than row, so if I create the following table:

 data = pd.DataFrame(data = {'Name':['This is a title', 'This is another title'], 'Number':[-5, -13]})

                     Name   Number
0   This is a title             -5
1   This is another title      -13

The creation of the 'Test' column yields:

can only convert an array of size 1 to a Python scalar

I understand why this is happening since the column now has more than one value, what I want to know is how can I do this with a dataframe that has more than one row? I've tried .items(), .values(), etc. and the new column just becomes NaN.

Any thoughts?

Thanks!

I'mahdi
  • 23,382
  • 5
  • 22
  • 30
bobby_pine
  • 41
  • 6

2 Answers2

1

You can use apply with axis=1 and move on dataframe row by row.

import pandas as pd
data = pd.DataFrame(data = {'Name':['This is a title', 'This is another title'], 'Number':[-5, -13]})

data['Test'] = data.apply(lambda row: row['Name'][:row['Number']], axis=1)
print(data)

Output:

                    Name  Number        Test
0        This is a title      -5  This is a 
1  This is another title     -13    This is 
I'mahdi
  • 23,382
  • 5
  • 22
  • 30
  • Thank you! I was trying to figure out how to lambda it, obviously couldn't figure it out. – bobby_pine Jul 05 '22 at 13:40
  • @bobby_pine, welcome. with apply(lambda row: ..., axis=1), we move row-wise and in each iteration, we get a row and we can get value on each column by name of the column and do what we like. you can see these two answers for different use of [`axis=1`](https://stackoverflow.com/a/52854800/1740577) and [`axis=0`](https://stackoverflow.com/a/70317839/1740577) on `apply` – I'mahdi Jul 05 '22 at 13:45
0

Unfortunately, here, you need to loop. A list comprehension will be the most efficient:

data['Test'] = [s[:i] for s,i in zip(data['Name'], data['Number'])]

output:

                    Name  Number        Test
0        This is a title      -5  This is a 
1  This is another title     -13    This is 
mozway
  • 194,879
  • 13
  • 39
  • 75