2016-12-30 8 views
1

으로 변환 나는 각 상점의 고기, 야채 및 빵 판매와 함께 아래 데이터 프레임을 가지고 있습니다. 값을 %로 변환하고 싶습니다. 예를 들어 Store N의 값은 74 %, 7 % 및 19 %가됩니다. 즉, 74 %는 매장 N의 총 판매량에 대한 고기 판매 비율입니다. 가장 간단한 방법은 무엇입니까?값을 %

import pandas as pd 

df=pd.DataFrame({'Store':['N','S','E','W'] 
        ,'Meat':[200,250,100,400] 
        ,'Veg':[20,100,30,80] 
        ,'Bread':[50,230,150,100]}) 
df=df[['Store','Meat','Veg','Bread']]  

enter image description here

답변

2

또한 람다 기능을 pandas.apply 사용할 수 있습니다

df.ix[:, 1:]=df.ix[:,1:].apply(lambda x: x*100/x.sum(), axis=1) 

당신에게 제공합니다

Store  Meat  Veg  Bread 
0  N 74.074074 7.407407 18.518519 
1  S 43.103448 17.241379 39.655172 
2  E 35.714286 10.714286 53.571429 
3  W 68.965517 13.793103 17.241379 
1

당신은 수동으로 비율을 계산할 수 있습니다

df['MeatPerc'] = df['Meat']/df['Meat'].sum()

4

주기를 사용하지 않고 순수 팬더 솔루션은 다음과 같습니다

df.ix[:, 1:] = (df.ix[:, 1:].T/df.ix[:, 1:].sum(1)).T 
print(df) 

결과 :

Store  Meat  Veg  Bread 
0  N 0.740741 0.074074 0.185185 
1  S 0.431034 0.172414 0.396552 
2  E 0.357143 0.107143 0.535714 
3  W 0.689655 0.137931 0.172414 
3

먼저 set_indexStore와 다음 sumdiv로 나눌 수 있습니다 마지막 reset_index :

df.set_index('Store', inplace=True) 
df = df.div(df.sum(1), axis=0) 
print (df.reset_index()) 
    Store  Meat  Veg  Bread 
0  N 0.740741 0.074074 0.185185 
1  S 0.431034 0.172414 0.396552 
2  E 0.357143 0.107143 0.535714 
3  W 0.689655 0.137931 0.172414 

ix 또는 iloc 의한 선택의 또 다른 해결 방법

df.ix[:,'Meat':] = df.ix[:,'Meat':].div(df.ix[:,'Meat':].sum(1), axis=0) 
print (df) 
    Store  Meat  Veg  Bread 
0  N 0.740741 0.074074 0.185185 
1  S 0.431034 0.172414 0.396552 
2  E 0.357143 0.107143 0.535714 
3  W 0.689655 0.137931 0.172414 

df.iloc[:,1:] = df.iloc[:,1:].div(df.iloc[:,1:].sum(1), axis=0) 
print (df) 
    Store  Meat  Veg  Bread 
0  N 0.740741 0.074074 0.185185 
1  S 0.431034 0.172414 0.396552 
2  E 0.357143 0.107143 0.535714 
3  W 0.689655 0.137931 0.172414 

타이밍 :

In [187]: %timeit (jez1(df)) 
100 loops, best of 3: 4.07 ms per loop 

In [188]: %timeit (jez2(df1)) 
100 loops, best of 3: 5.61 ms per loop 

In [189]: %timeit (jez3(df2)) 
100 loops, best of 3: 5.44 ms per loop 

In [190]: %timeit (ric(df3)) 
100 loops, best of 3: 6.18 ms per loop 

In [191]: %timeit (ogi(df4)) 
1 loop, best of 3: 2.2 s per loop 

코드 타이밍 S :

,
#random dataframe 
np.random.seed(100) 

#10 data columns + first Store col, 10k rows 
df = pd.DataFrame(np.random.randint(10, size=(10000,10)), columns=list('ABCDEFGHIJ')) 
df.index = 'a' + df.index.astype(str) 
df = df.reset_index().rename(columns={'index':'Store'}) 
print (df) 
df1, df2, df3, df4 = df.copy(), df.copy(), df.copy(), df.copy() 

def jez1(df): 
    df = df.set_index('Store') 
    df = 100 * df.div(df.sum(1), axis=0) 
    return (df.reset_index()) 


def jez2(df): 
    df.ix[:,'A':] = df.ix[:,'A':].div(df.ix[:,'A':].sum(1), axis=0) 
    return df 
def jez3(df):  
    df.iloc[:,1:] = df.iloc[:,1:].div(df.iloc[:,1:].sum(1), axis=0) 
    return df 

def ric(df):  
    df.ix[:, 1:] = (df.ix[:, 1:].T/df.ix[:, 1:].sum(1)).T 
    return df 

def ogi(df):  
    df.ix[:, 1:]=df.ix[:,1:].apply(lambda x: x/x.sum(), axis=1) 
    return df  

print (jez1(df)) 
print (jez2(df1)) 
print (jez3(df2)) 
print (ric(df3)) 
print (ogi(df4)) 
+0

나는 당신을 선호합니다. 'set_index'와'div'를 사용하는 것은 인덱스와 트랜스 포즈를 사용하는 것보다 훨씬 우아합니다. –

+0

@RicardoCruz - 의견을 주셔서 감사합니다. – jezrael