2016-07-25 3 views
4

Ich habe die folgenden Pandas DataFrame.Pandas Dataframe: Wie werden Ganzzahlen in eine Kette von 0 und 1 zerlegt?

import pandas as pd 
df = pd.read_csv('filename.csv') 

print(df) 

     sample  column_A   
0  sample1  6/6  
1  sample2  0/4 
2  sample3  2/6  
3  sample4  12/14 
4  sample5  15/21 
5  sample6  12/12 
.. .... 

Die Werte in column_A nicht Fraktionen, und diese Daten müssen so manipuliert werden, dass I umwandeln kann jeden Wert in 0s und 1s (die ganzen Zahlen in ihre binären Pendants nicht konvertieren).

Der "Zähler" oben gibt die Gesamtzahl von 1s, während der "Nenner" gibt die Gesamtzahl der 0s und 1s zusammen.

So soll die Tabelle tatsächlich in folgendem Format sein:

 sample  column_A   
0  sample1  111111  
1  sample2  0000 
2  sample3  110000  
3  sample4  11111111111100  
4  sample5  111111111111111000000 
5  sample6  111111111111 
.. .... 

Ich habe noch nie eine ganze Zahl an Ausgabestrings von 0 und 1 wie folgt analysiert. Wie macht man das? Gibt es eine "Pandas-Methode" mit lambda Ausdrücken? Pythonic String Parsing oder Regex?

+1

I String-Parsing sagen würde, mit so etwas wie ' a, b = Karte (int, field.split ('/')); Ergebnis = '1' * a + '0' * (b-a) '. – TigerhawkT3

Antwort

6

Zuerst nehme an, Sie eine Funktion schreiben:

def to_binary(s): 
    n_d = s.split('/') 
    n, d = int(n_d[0]), int(n_d[1]) 
    return '1' * n + '0' * (d - n) 

Damit,

>>> to_binary('4/5') 
'11110' 

Jetzt müssen Sie nur verwenden pandas.Series.apply:

df.column_A.apply(to_binary) 
4

Eine Alternative:

df2 = df['column_A'].str.split('/', expand=True).astype(int)\ 
        .assign(ones='1').assign(zeros='0') 

df2 
Out: 
    0 1 ones zeros 
0 6 6 1  0 
1 0 4 1  0 
2 2 6 1  0 
3 12 14 1  0 
4 15 21 1  0 
5 12 12 1  0 

(df2[0] * df2['ones']).str.cat((df2[1]-df2[0])*df2['zeros']) 
Out: 
0     111111 
1      0000 
2     110000 
3   11111111111100 
4 111111111111111000000 
5    111111111111 
dtype: object 

Hinweis: Ich habe tatsächlich versucht, eine schnellere Alternative zu finden denken, gelten würde langsam sein, aber dieses erweist sich als langsamer.

+0

Ich mag diese Lösung, aber @AmiTavory hatte vorher eine anständige Antwort. Ich denke, es könnte auch schneller sein, aber ich habe das nicht überprüft. Ich wünschte, ich könnte beide Fragen akzeptieren! – ShanZhengYang

+0

@ShanZhengYang Vielen Dank, aber Sie haben diese als richtig markiert. Ich denke, Sie wollten Ami Tavorys Antwort markieren (was auch meine Wahl wäre). – ayhan

+1

Es ist sehr interessante Frage und ich mag beide Antworten. Hier ist mein Versuch, es als Einzeiler zu machen: 'df.column_A.str.extract (r '(? P \ d +)/(? P \ d +)', expand = Wahr) .astype (int) .apply (Lambda x: ['1'] * x.one + ['0'] * (x.len-x.one), Achse = 1) .apply (''. join) '- es wird langsamer , wollte nur einen Einzeiler haben ...;) – MaxU

1

Hier sind einige alternativen Lösungen extract() und .str.repeat() Methoden:

In [187]: x = df.column_A.str.extract(r'(?P<ones>\d+)/(?P<len>\d+)', expand=True).astype(int).assign(o='1', z='0') 

In [188]: x 
Out[188]: 
    ones len o z 
0  6 6 1 0 
1  0 4 1 0 
2  2 6 1 0 
3 12 14 1 0 
4 15 21 1 0 
5 12 12 1 0 

In [189]: x.o.str.repeat(x.ones) + x.z.str.repeat(x.len-x.ones) 
Out[189]: 
0     111111 
1      0000 
2     110000 
3   11111111111100 
4 111111111111111000000 
5    111111111111 
dtype: object 

oder ein langsamer (zwei apply()) Einzeiler:

In [190]: %paste 
(df.column_A.str.extract(r'(?P<one>\d+)/(?P<len>\d+)', expand=True) 
    .astype(int) 
    .apply(lambda x: ['1'] * x.one + ['0'] * (x.len-x.one), axis=1) 
    .apply(''.join) 
) 
## -- End pasted text -- 
Out[190]: 
0     111111 
1      0000 
2     110000 
3   11111111111100 
4 111111111111111000000 
5    111111111111 
dtype: object 
Verwandte Themen