在一列中将小数格式化为百分数

4

假设我有以下pandas DataFrame:

df = pd.DataFrame({'name': ['Johnny', 'Brad'], 'rating': [1.0, 0.9]})

我希望将“评分”列从小数转换为字符串百分数格式(例如,将1.0转换为'100%')。以下代码可以实现该功能:
def decimal_to_percent_string(row):
    return '{}%'.format(row['rating'] * 100)

df['rating'] = df.apply(func=decimal_to_percent_string, axis=1)

对我来说,这似乎非常低效,因为它将函数应用于整个DataFrame,这并不理想,因为我的DataFrame非常大。有更好的方法吗?

4个回答

11

使用 Pandas 的广播运算:

df.rating = (df.rating * 100).astype(str) + '%'
df 
     name  rating
0  Johnny  100.0%
1    Brad   90.0%

或者,使用 df.muldf.add

df.rating = df.rating.mul(100).astype(str).add('%')
df
     name  rating
0  Johnny  100.0%
1    Brad   90.0%

1
df['rating'] = df['rating'].mul(100).astype(int).astype(str).add('%')
print(df)

输出:

     name rating
0  Johnny   100%
1    Brad    90%

1

1. 仅显示的解决方案

如果您只想让DataFrame将该列显示为%,最好使用格式化程序,因为这样rating列实际上并没有改变,因此您可以对其执行进一步的操作。

df.style.format({'rating': '{:.2%}'.format})

现在,print(df) 将显示:
     name  rating
0  Johnny 100.00%
1    Brad  90.00%

2. 转换解决方案

如果您确实需要将字段转换为字符串(例如用于ETL目的),则此命令在大型和小型数据框上都更加惯用且速度最快:

df['rating'] = df['rating'].apply('{:.2%}'.format)

现在rating列是一个字符串,并且它的显示结果与上面的结果完全相同。

速度测试

import sys
import timeit
import pandas as pd

print(f"Pandas: {pd.__version__} Python: {sys.version[:5]}\n")

for cur_size in [1, 10, 100, 1000, 10000, 100000, 1000000]:
    mysetup = (f"import pandas as pd; df = pd.DataFrame({{"
        f"'name': ['Johnny', 'Brad']*{cur_size}, "
        f"'rating': [1.0, 0.9]*{cur_size}}}); "
        f"ff = '{{:.2f}}%'.format")

    cs95    = "df.rating.mul(100).astype(str).add('%')"
    michael = "df['rating'].apply(ff)"

    speeds = []
    for stmt in [cs95, michael]:
        speeds.append(timeit.timeit(setup=mysetup, stmt=stmt, number=100))

    print(f"Length: {cur_size*2}.  {speeds[0]:.2f}s vs {speeds[1]:.2f}s")

结果:

Pandas: 1.4.3 Python: 3.9.7

Length: 2.         0.02s vs  0.01s
Length: 20.        0.02s vs  0.02s
Length: 200.       0.03s vs  0.03s
Length: 2000.      0.09s vs  0.08s
Length: 20000.     0.79s vs  0.65s
Length: 200000.    8.44s vs  6.94s
Length: 2000000.  90.44s vs 73.57s

结论:在 Pandas 和 Python 中,apply 方法更符合惯用语,并且对于较大的数据框具有显着的性能优势。

0

试试这个:

df['rating'] = pd.Series(["{0:.2f}%".format(val*100) for val in df['rating']], index = df.index)
print(df)

输出为:

     name    rating
0   Johnny   100.00%
1   Brad     90.00%

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接