2016-07-13 50 views
5

basamak sayısına bağlı ve değeri her zamanBölünmüş pandalar dataframe sütun ben iki sütun anahtar ve değer olan bir pandalar dataframe var

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

gibi 8 haneli bir numara şey oluşur Şimdi almak gerekir değer sütunu ve benim sonuç

>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 

Ben girdi veri biçimini değiştiremezsiniz yeni bir veri çerçevesi olacak şekilde, mevcut hane üzerinde bölünmüş, diye düşündüm en geleneksel şey bir dizeye ve döngü değeri dönüştürmek oldu her rakam char ile ve bir liste içine koymak, ancak Daha zarif ve hızlı bir şey için oking, lütfen yardım edin.

DÜZENLEME: Giriş dize değil, tamsayıdır.

+0

Başlamak için dizeler olarak "değer" sütununda bu öğeler yok mu? Ya da baştaki sıfırları nasıl alabilirsin? – Divakar

+0

soru düzenlenmiş, baştaki sıfırları toplayarak benim kötü olan –

cevap

3

Tek bir yaklaşım olabilir: -

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

Numune koşmak -

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 değil -48 ile bölünmelidir? –

+0

@johnsmith Nah, ascii eşdeğerini alıyor. Yani, 0 '' 48' ve '' '' '' '' olur. Yani, geri almak için 48 çıkartıyoruz. – Divakar

3

sonra aşağıdaki eserler (poz olarak, 8) girişinizi dizeleri olarak depolanır ve aynı uzunluğa sahip varsayarsak:

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

Bu çalışması gerekir:

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

enter image description here

+0

Müthiş teşekkürler çok, benim kullanım durumum için çok iyi çalışıyor –

2

bir vectorized versiyonu olacaktır:

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

bu ilk böler sonra karakterler arasındaki boşlukları tanıtır ve. Bu sadece str.split kullanabilmek için bir geçici çözüm (belki de gerekli değil, emin değil). Ama oldukça hızlıdır:

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 

Güncelleme: Divakar's solution hızlı gibi görünüyor.

İlgili konular