2016-12-20 3 views
4

저는 파이썬에 익숙하지 않고 약간의 문제가 있습니다. 나는 다음과 같은 dataframe이 : 나는 다음과 같은 형식에 매핑 할열을 여러 열로 변경하십시오.

import pandas as pd 
data = {'v1':('Belgium[country]', 'Antwerp[city]', 'Gent[city]', 'France[country]', 'Paris[city]', 'Marseille[city]', 'Toulouse[city]', 'Spain[country]', 'Madrid[city]')} 
df = pd.DataFrame(data) 
df 

    v1 
0 Belgium[country] 
1 Antwerp[city] 
2 Gent[city] 
3 France[country] 
4 Paris[city] 
5 Marseille[city] 
6 Toulouse[city] 
7 Spain[country] 
8 Madrid[city] 

:

v1    v2 
0 Belgium[country] Antwerp[city] 
1 Belgium[country] Gent[city] 
2 France[country] Paris[city] 
3 France[country] Marseille[city] 
4 France[country] Toulouse[city] 
5 Spain[country] Madrid[city] 

나는 사전을 사용하여이 작업을 수행하는 방법을 발견,하지만 난 순서를 유지 보수 할 때부터 목록을 사용하여 이렇게하는 방법을 찾고 있습니다.

인덱스와 값 자체 (구체적으로 [country]와 [city])를 기반으로했는데 둘 다 실패했습니다. 어떤 도움을 많이 주시면 감사하겠습니다!

+0

귀하의 예제의 정의에서 모든 국가가 도시로 표시됩니다. – IanS

+0

당신 말이 맞아요, 제가 고쳐졌습니다 – LRA

답변

2

이 작동합니다 :

counter = df['v1'].str.contains('country').cumsum() 
result = df.groupby(counter).apply(lambda g: g[1:]).reset_index(level=1, drop=True) 
result = result.rename(columns={'v1': 'v2'}).reset_index(drop=False) 
result['v1'] = result['v1'].replace(df.groupby(counter).first().squeeze()) 

아이디어는 각각의 새로운 국가 증가되는 카운터를 추가하는 것입니다. 그런 다음이 카운터로 그룹화하여 필요한 정보에 액세스 할 수 있습니다.

특히 첫 번째 단계는 도시 만 유지하는 것입니다 (각 그룹에 대해 g[1:]g). 그런 다음 이름을 변경하고 다시 색인화하십시오. 마지막으로 다른 그룹의 결과 (국가에 부여)를 사용하여 v1 열의 값을 바꿉니다. groupby없이

+0

이것은 완벽하게 작동합니다, 감사합니다! – LRA

2

솔루션 :

#rename columns 
df = df.rename(columns={'v1':'v2'}) 
#get counter 
counter= df.v2.str.contains('country').cumsum() 
#get mask where are changed country to city 
df.insert(0, 'v1', df.loc[counter.ne(counter.shift()), 'v2']) 
#forward filling NaN 
df.v1 = df.v1.ffill() 
#remove rows where v1 == v2 
df = df[df.v1.ne(df.v2)].reset_index(drop=True) 

print (df) 
       v1    v2 
0 Belgium[country] Antwerp[city] 
1 Belgium[country]  Gent[city] 
2 France[country]  Paris[city] 
3 France[country] Marseille[city] 
4 France[country] Toulouse[city] 
5 Spain[country]  Madrid[city] 

타이밍 : 타이밍에 대한

In [189]: %timeit (jez(df)) 
100 loops, best of 3: 2.47 ms per loop 

In [191]: %timeit (IanS(df1)) 
100 loops, best of 3: 5.06 ms per loop 

코드 :

def jez(df): 
    df = df.rename(columns={'v1':'v2'}) 
    counter= df.v2.str.contains('country').cumsum() 
    df.insert(0, 'v1', df.loc[counter.ne(counter.shift()), 'v2']) 
    df.v1 = df.v1.ffill() 
    df = df[df.v1.ne(df.v2)].reset_index(drop=True) 

    return (df) 

def IanS(df): 
    counter = df['v1'].str.contains('country').cumsum() 
    result = df.groupby(counter).apply(lambda g: g[1:]).reset_index(level=1, drop=True) 
    result = result.rename(columns={'v1': 'v2'}).reset_index(drop=False) 
    result['v1'] = result['v1'].replace(df.groupby(counter).first().squeeze()) 
    return (result) 
+0

감사합니다. – LRA

관련 문제