2016-12-06 1 views
2

분명히 보이는 팬더에서 계산을 시도하고 있지만 여러 번 시도한 후에 올바르게 수행하는 방법을 찾지 못했습니다.팬더의 행 값에 따라 열을 나눕니다.

df = pd.DataFrame([["A", "a", 10.0], 
        ["A", "b", 12.0], 
        ["A", "c", 13.0], 
        ["B", "a", 5.0 ], 
        ["B", "b", 6.0 ], 
        ["B", "c", 7.0 ]]) 

첫 번째 열은 두 번째 열은 클래스이고, 세 번째 열은 시간을 제공하는 시험 이름 :

는 I이 닮은 dataframe있다. 각 테스트는 일반적으로 3 개의 클래스가있는 테이블에 있습니다.

이이처럼 그릴 수있는 올바른 형식은 다음과 같습니다

sns.factorplot(x="2", y="0", hue="1", data=df, 
       kind="bar") 

은 그래서 각 테스트를 위해, 나는 3 개 개의 바, 각 클래스에 대한 하나의 그룹을 얻을.

그러나 2 열의 각 값이 절대 값이 아니지만 클래스 "a"와 비교되는 비율로 데이터 프레임을 변경하고 싶습니다.

그래서이로 변환하고 싶습니다 :

df = pd.DataFrame([["A", "a", 1.0], 
        ["A", "b", 1.2], 
        ["A", "c", 1.3], 
        ["B", "a", 1.0], 
        ["B", "b", 1.2], 
        ["B", "c", 1.4]]) 

를이 일치하도록 내가 예를 들어, 계산을 수행 시리즈를 추출하는 인덱스를 변경할 수 있어요 :

df_a = df[df[1] == "a"].set_index(0) 
df_b = df[df[1] == "b"].set_index(0) 
df_b["ratio_a"] = df_b[2]/df_a[2] 

하지만 이것은 확실히 비효율적이며 형식으로 다시 그룹화해야합니다.

올바른 방법은 무엇입니까?

답변

2

당신은 또한 일부 인덱스 정렬하여이 작업을 수행 할 수 있습니다 얻을 수 있습니다.

df1 = df.set_index(['test', 'class']) 
df1/df1.xs('a', level='class') 

그러나 변형이 좋은

+0

고마워,이 잘 작동합니다! – Dric512

4

각 그룹의 첫 번째 값을 찾기 위해 groupby/transform('first')을 사용할 수

import pandas as pd 
df = pd.DataFrame([["A", "a", 10.0], 
        ["A", "b", 12.0], 
        ["A", "c", 13.0], 
        ["B", "b", 6.0 ], 
        ["B", "a", 5.0 ], 
        ["B", "c", 7.0 ]]) 
df = df.sort_values(by=[0,1]) 
df[2] /= df.groupby(0)[2].transform('first') 

0 1 2 
0 A a 1.0 
1 A b 1.2 
2 A c 1.3 
3 B a 1.0 
4 B b 1.2 
5 B c 1.4 
+0

좋습니다. 'df.groupby (0) [2] .transform (lambda x : x/x.iloc [0])'또한 괜찮을 것입니다. – Zero

+0

@JohnGalt :'transform ('first')'와 같은 "내장"함수는 Cython 화되어 있으므로'lambda x : x/x.iloc [0]'과 같은 맞춤 함수로 변환하는 것보다 훨씬 빠르게 실행됩니다. 그러나 그렇습니다. 같은 결과를 낳을 것입니다. – unutbu

+0

이것은 좋아 보인다. "첫 번째"가 올바른 레이블인지 보장하려면 먼저 열 1로 데이터 프레임을 정렬해야합니까? – Dric512