2016-06-29 11 views
4

Ich habe eine Zeile in einem Pandas-Datenrahmen, der die Verkaufsrate meiner Artikel enthält.Pandas: Ändern einer bestimmten Zeile in Prozentsätze

Ein Blick auf meine Daten:

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 

ich das, indem Sie nach dem Verkaufs% leicht berechnen:

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 

Nun, was ich zu tun versucht, ist die „Total Sales zu ändern Rate "Zeile zu ganze Zahl Prozentsätze. Ich bin in der Lage, dies zu tun, wenn es eine Spalte war, aber ich stoße auf Probleme, wenn ich mit Reihen arbeite.

Hier ist, was ich versucht:

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 

Die Berechnungen sind aus/nach links verschoben. Die Verkaufsrate für Monat 1 ist die Verkaufsrate für Monat 2 (39%)!

Antwort

6

könnten Sie verwenden .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) 

Ausbeuten

    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% 

Beachten Sie, dass die Python str.format Methode eine built-in % format hat, die die Zahl von 100 und zeigt in festen ('f') Format multipliziert, gefolgt von einem Prozentzeichen.


Es ist wichtig zu wissen, dass Pandas DataFrame-Spalten einen einzelnen dtype haben müssen. Wenn Sie einen Wert in eine Zeichenfolge ändern, wird die gesamte Spalte gezwungen, ihren Dtyp in den allgemeinen Typ object dtype zu ändern. So werden die int64 s oder int32 s in den Total Listings und Total Sales Zeilen als einfache Python ints Zeilen umformatiert. Diese verhindert, dass Pandas von schnellen NumPy-basierten numerischen Operationen profitieren, die nur mit nativen NumPy dtypes funktionieren (wie int64 oder float64 - nicht object).

So, während der obige Code das gewünschte Aussehen erreicht, ist es nicht ratsam, dies zu verwenden, wenn weitere Berechnungen auf dem DataFrame durchgeführt werden sollen. Konvertieren Sie stattdessen nur in Strings am Ende, wenn Sie dies für die Präsentation tun müssen.

Oder alternativ transponieren Ihre Datenrahmen, so dass die Total Sales Rate Strings in einer Spalte sind, nicht eine Zeile:

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) 

ergibt

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% 

Der Grund, warum

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

Die Werte nach links wurden um eine Spalte verschoben, weil die neue Serie einen Index hat, der bei 0 nicht 1 beginnt.Pandas richtet den Index der Serie auf der rechten Seite mit dem Index block_combine.loc["Total Sales Rate"] vor dem Zuweisen von Werten zu block_combine.loc["Total Sales Rate"] aus.

So könnte man alternativ verwendet hat:

block_combine.loc["Total Sales Rate"] = pd.Series(["{0:.0f}%".format(val * 100) 
    for val in block_combine.loc["Total Sales Rate"]], 
    index=block_combine.columns) 
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) 

Ergebnis ...

    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 
Verwandte Themen