熊猫:将特定行更改为百分比

时间:2016-06-29 18:19:34

标签: python pandas dataframe

我在Pandas数据框中有一行,其中包含我的项目的销售率。

查看我的数据:

block_combine
Out[78]: 
END_MONTH         1    2    3   4    5
Total Listings  168  219  185  89  112
Total Sales      85   85   84  41   46

我可以通过以下方式轻松计算销售额百分比:

block_combine.loc["Total Sales Rate"] = block_combine.ix[1,:] / block_combine.ix[0,:]
block_combine

Out[79]: 
END_MONTH                  1           2           3          4           5
Total Listings    168.000000  219.000000  185.000000  89.000000  112.000000
Total Sales        85.000000   85.000000   84.000000  41.000000   46.000000
Total Sales Rate    0.505952    0.388128    0.454054   0.460674    0.410714

现在我要做的是将“总销售率”行更改为整数百分比。如果它是一个列,我可以这样做但是当我使用行时遇到问题。

以下是我的尝试:

block_combine.loc["Total Sales Rate"] = pd.Series(["{0:.0f}%".format(val * 100) for val in block_combine.loc["Total Sales Rate"]])


block_combine

Out[81]: In [82]: 
END_MONTH           1    2    3    4      5
Total Listings    168  219  185   89  112.0
Total Sales        85   85   84   41   46.0
Total Sales Rate  39%  45%  46%  41%    NaN

计算关闭/向左移动。第1个月的销售率实际上是第2个月的销售率(39%)!

2 个答案:

答案 0 :(得分:7)

您可以使用.apply('{:.0%}'.format)

import pandas as pd

df = pd.DataFrame([(168,219,185,89,112), (85,85,84,41,46)], 
                  index=['Total Listings', 'Total Sales'], columns=list(range(1,6)))
df.loc['Total Sales Rate'] = ((df.loc['Total Sales']/df.loc['Total Listings'])
                              .apply('{:.0%}'.format))

print(df)

产量

                    1    2    3    4    5
Total Listings    168  219  185   89  112
Total Sales        85   85   84   41   46
Total Sales Rate  51%  39%  45%  46%  41%

请注意,Python str.format方法有一个built-in % format,它将数字乘以100并以固定('f')格式显示,后跟百分号。

请务必注意,Pandas DataFrame列必须具有单个dtype。将一个值更改为字符串会强制更改整个列 它的dtype为通用object dtype。因此,int64int32 s Total ListingsTotal Sales行将重新命名为普通Python ints。这个 防止Pandas利用快速基于NumPy的数值运算 它只适用于原生NumPy dtypes(如int64float64 - 不是 object)。

因此,虽然上述代码达到了预期的效果,但建议不要使用 这是否要在DataFrame上进行进一步的计算。相反,只转换 如果您需要这样做以便演示,最后到字符串。

或者,转换您的DataFrame以使Total Sales Rate字符串位于列中,而不是一行:

import pandas as pd

df = pd.DataFrame([(168,219,185,89,112), (85,85,84,41,46)], 
                  index=['Total Listings', 'Total Sales'], columns=list(range(1,6))).T

df['Total Sales Rate'] = ((df['Total Sales']/df['Total Listings'])
                              .apply('{:.0%}'.format))

print(df)

产量

   Total Listings  Total Sales Total Sales Rate
1             168           85              51%
2             219           85              39%
3             185           84              45%
4              89           41              46%
5             112           46              41%

原因

block_combine.loc["Total Sales Rate"] = pd.Series(["{0:.0f}%".format(val * 100) for val in block_combine.loc["Total Sales Rate"]])

将值向左移动一列是因为新系列的索引从0开始而不是1. Pandas 对齐右侧系列的索引,其索引为{{在为block_combine.loc["Total Sales Rate"]分配值之前1}}。

因此,您可以使用:

block_combine.loc["Total Sales Rate"]

答案 1 :(得分:0)

df = pd.DataFrame({
        1: [168,85], 
        2: [219,85],  
        3: [185,84],  
        4: [89,41], 
        5: [112,46]
    }, index=['Total Listings', 'Total Sales'])

total_sales_rate = pd.Series(df.loc['Total Sales'] / df.loc['Total Listings'] * 100, name='Total Sales Rate').round()
df = df.append(total_sales_rate)

结果...

                    1    2    3   4    5
Total Listings    168  219  185  89  112
Total Sales        85   85   84  41   46
Total Sales Rate   51   39   45  46   41