2016-07-13 10 views
5

자리의 수에 따라, 값은 항상분할 팬더 dataframe 열 나는 두 개의 열이 키와 값이있는 팬더 dataframe이

>df1 
key value 
10 10000100 
20 10000000 
30 10100000 
40 11110000 

같은 8 자리 숫자 뭔가 구성이 지금은 응시해야 값 열은 내 결과가

>df_res 
key 0 1 2 3 4 5 6 7 
10 1 0 0 0 0 1 0 0 
20 1 0 0 0 0 0 0 0 
30 1 0 1 0 0 0 0 0 
40 1 1 1 1 0 0 0 0 

내가 입력 데이터 형식을 변경할 수있는 새로운 데이터 프레임이되도록, 현재의 자리에 분할, 내가 생각했던 가장 일반적인 것은 문자열 및 루프로 값을 변환하는 것이 었습니다 그러나 각 자릿수를 통해 목록에 넣으십시오. 더 우아하고 빠른 뭔가를 oking, 친절하게 도움이됩니다.

EDIT : 입력이 문자열에 없습니다. 정수입니다.

+0

'value' 열에 이러한 요소가 시작되지 않습니까? 그렇지 않으면 어떻게 그 안에 제로를 넣을 수 있습니까? – Divakar

+0

질문이 편집되었습니다. 예제에서 앞에 0을 추가하는 것이 좋지 않습니다. –

답변

3

한 접근법은 다음과 같을 수 있습니다.

arr = df.value.values.astype('S8') 
df = pd.DataFrame(np.fromstring(arr, dtype=np.uint8).reshape(-1,8)-48) 

샘플 실행 -

In [58]: df 
Out[58]: 
    key  value 
0 10 10000100 
1 20 10000000 
2 30 10100000 
3 40 11110000 

In [59]: arr = df.value.values.astype('S8') 

In [60]: pd.DataFrame(np.fromstring(arr, dtype=np.uint8).reshape(-1,8)-48) 
Out[60]: 
    0 1 2 3 4 5 6 7 
0 1 0 0 0 0 1 0 0 
1 1 0 0 0 0 0 0 0 
2 1 0 1 0 0 0 0 0 
3 1 1 1 1 0 0 0 0 
+0

은 -48이 아닌 48로 나누어 져야합니다. –

+0

@ johnsmith Nah, 그 ascii 동등한지고. 따라서 '0'은 '48'이되고 '1'은 '49'가됩니다. 따라서 int를 되 찾으려면 48을 뺍니다. – Divakar

3

다음 작품 (제기로, 8) 당신의 입력 문자열로 저장되며, 모두 같은 길이가 가정 :

df1 = pd.concat([df1,pd.DataFrame(columns=range(8))]) 
df1[list(range(8))] = df1['Value'].apply(lambda x: pd.Series(list(str(x)),index=range(8))) 
9

이 작동합니다 :

df.value.astype(str).apply(list).apply(pd.Series).astype(int) 

enter image description here

+0

굉장히 감사합니다. –

2

vectorized 버전은 다음과 같습니다

df['value'].astype(str).str.join(' ').str.split(' ', expand=True) 

첫 번째는 분할 후 문자 사이에 공백을 소개하고. str.split을 사용할 수있는 해결 방법 일뿐입니다 (어쩌면 불필요 할 수도 있음). 하지만 매우 빠릅니다.

df = pd.DataFrame({'value': np.random.randint(10**7, 10**8, 10**4)}) 

%timeit df['value'].astype(str).str.join(' ').str.split(' ', expand=True) 
10 loops, best of 3: 25.5 ms per loop 

%timeit df.value.astype(str).apply(list).apply(pd.Series).astype(int) 
1 loop, best of 3: 1.27 s per loop 

%timeit df['value'].apply(lambda x: pd.Series(list(str(x)),index=range(8))) 
1 loop, best of 3: 1.33 s per loop 


%%timeit 
arr = df.value.values.astype('S8') 
pd.DataFrame(np.fromstring(arr, dtype=np.uint8).reshape(-1,8)-48) 

1000 loops, best of 3: 1.14 ms per loop 

업데이트 : Divakar's solution이 가장 빠릅니다.