Why doesn't f-strings formatting work for Pandas DataFrames?

Question:

Given a DataFrame with Product Id and Amount:

df = pd.DataFrame([['504145', 12000.0],
                   ['555933', 23010.5]],
                  columns=['Product Id', 'Amount'])
df
Out[1]: 
  Product Id   Amount
0     504145  12000.0
1     555933  23010.5

I want to add a “Description” column based on Amount, which is expected to look like:

  Product Id   Amount        Description
0     504145  12000.0  Amount is 12000.0
1     555933  23010.5  Amount is 23010.5

When I use f-strings formatting, the result is aggregating the whole column Amount as a series instead of using the value of a particular row for string concatenation:

df['Description'] = f'Amount is {df["Amount"].astype(str)}'
df
Out[2]: 
  Product Id   Amount                                        Description
0     504145  12000.0  Amount is 0    12000.0n1    23010.5nName: Am...
1     555933  23010.5  Amount is 0    12000.0n1    23010.5nName: Am...

However, it works fine with simple string concatenation using +:

df['Description'] = "Amount is " + df["Amount"].astype(str)
df
Out[9]: 
  Product Id   Amount        Description
0     504145  12000.0  Amount is 12000.0
1     555933  23010.5  Amount is 23010.5

Why does f-strings formatting in a Pandas DataFrame behave like that? How should I fix it to use f-strings formatting? Or is it not suggested to use f-strings formatting for string concatenation in Pandas?

Asked By: henrywongkk

||

Answers:

You need iterate by each value, e.g. by apply:

df['Description'] = df["Amount"].apply(lambda x: f'Amount is {x}')

Or by list comprehension:

df['Description'] = [f'Amount is {x}' for x in df["Amount"]]

print (df)

  Product Id   Amount        Description
0     504145  12000.0  Amount is 12000.0
1     555933  23010.5  Amount is 23010.5

Your solution:

df['Description'] = f'Amount is {df["Amount"].astype(str)}'

working different – it append each value of Series (also with index) to strings and repeat like constant for all values of new column.

Answered By: jezrael

Another option could be to use agg and format:

df['description'] = df.agg('Amount is {0[Amount]}'.format, axis=1)
Answered By: sbha