1

多くの提案の後、私は R スクリプトを Python に移行し始めています。R での作業のほとんどはデータ フレームに関係しておりDataFrame、pandas パッケージのオブジェクトを使用しています。私のスクリプトでは、csv ファイルを読み込んで、データをDataFrameオブジェクトにインポートする必要があります。次に、16 進数値をDATAビット単位のデータにラベル付けされた列に変換し、ビットごとに 1 つずつ、16 個の新しい列を作成する必要があります。

ファイル内の入力データの例test.txtは次のようになります。

プレフィックス、テスト、ゾーン、行、列、データ

6_6,読み取り,0, 0, 0,BFED

6_6,READ,0,1,0,BB7D

6_6,READ,0,2,0,FFF7

6_6、読み取り、0、3、0、E7FF

6_6,読み取り,0, 4, 0,FBF8

6_6,読み取り,0, 5, 0,DE75

6_6,読み取り,0, 6, 0,DFFE

私のpythonスクリプトtest.pyは次のとおりです。

import glob

import pandas as pd

import numpy as np

fname = 'test.txt'

df = pd.read_csv(fname, comment="#")

dfs = df[df.TEST == 'READ']

# function to convert the hexstring into a binary string

def hex2bin(hstr):

    return bin(int(hstr,16))[2:]


# convert the hexstring in column DATA to binarystring ROWDATA

dfs['BINDATA'] = dfs['DATA'].apply(hex2bin)

# get rid of the column DATA

del dfs['DATA']

このスクリプトを実行してオブジェクトを検査するとdfs、次のようになります。

プレフィックス テスト ゾーン ROW COL BINDATA

0 6_6 読み取り 0 0 0 1011111111101101

1 6_6 読み取り 0 1 0 1011101101111101

2 6_6 読み取り 0 2 0 1111111111110111

3 6_6 読み取り 0 3 0 1110011111111111

4 6_6 読み取り 0 4 0 1111101111111000

5 6_6 読み取り 0 5 0 1101111001110101

6 6_6 読み取り 0 6 0 1101111111111110

したがって、名前付きの列BINDATAを16個の新しい列に分割する方法がわかりません(B0、B0、B2、....、B15という名前にすることができます)。どんな助けでも大歓迎です。

ありがとうございます。それでは、お元気で、

デリック。

4

2 に答える 2

4

もっと簡単に(forループなしで)できるかどうかはわかりませんが、これでうまくいきます:

for i in range(16):
    dfs['B'+str(i)] = dfs['BINDATA'].str[i]

シリーズのstr属性は、各要素に作用するいくつかのベクトル化された文字列メソッドへのアクセスを提供します (ドキュメントを参照してください: http://pandas.pydata.org/pandas-docs/stable/basics.html#vectorized-string-methods )。この場合、さまざまな文字にアクセスするために文字列にインデックスを付けるだけです。
これは私に与えます:

In [20]: dfs
Out[20]:
            BINDATA B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15
0  1011111111101101  1  0  1  1  1  1  1  1  1  1   1   0   1   1   0   1
1  1011101101111101  1  0  1  1  1  0  1  1  0  1   1   1   1   1   0   1
2  1111111111110111  1  1  1  1  1  1  1  1  1  1   1   1   0   1   1   1
3  1110011111111111  1  1  1  0  0  1  1  1  1  1   1   1   1   1   1   1
4  1111101111111000  1  1  1  1  1  0  1  1  1  1   1   1   1   0   0   0
5  1101111001110101  1  1  0  1  1  1  1  0  0  1   1   1   0   1   0   1
6  1101111111111110  1  1  0  1  1  1  1  1  1  1   1   1   1   1   1   0

.astype(int)文字列ではなく int として使用する場合は、for ループに追加できます。


編集:それを行う別の方法(ワンライナーですが、2番目のステップで列名を変更する必要があります):

In [34]: splitted = dfs['BINDATA'].apply(lambda x: pd.Series(list(x)))

In [35]: splitted.columns = ['B'+str(x) for x in splitted.columns]

In [36]: dfs.join(splitted)
Out[36]:
            BINDATA B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15
0  1011111111101101  1  0  1  1  1  1  1  1  1  1   1   0   1   1   0   1
1  1011101101111101  1  0  1  1  1  0  1  1  0  1   1   1   1   1   0   1
2  1111111111110111  1  1  1  1  1  1  1  1  1  1   1   1   0   1   1   1
3  1110011111111111  1  1  1  0  0  1  1  1  1  1   1   1   1   1   1   1
4  1111101111111000  1  1  1  1  1  0  1  1  1  1   1   1   1   0   0   0
5  1101111001110101  1  1  0  1  1  1  1  0  0  1   1   1   0   1   0   1
6  1101111111111110  1  1  0  1  1  1  1  1  1  1   1   1   1   1   1   0
于 2013-08-03T15:53:28.020 に答える
1

ループなしでこれを行う方法は次のとおりです (ただし、このコードには多くの暗黙的なループがあるため、実際にはそうではありません)。

import pandas as pd

# read the above frame from the clipboard
df = pd.read_clipboard(converters={'BINDATA': str})
df = df.fillna(nan).replace('None', nan).dropna(axis=0, how='all')

# here are the lines that matter
bindata = df.BINDATA.apply(list).apply(Series)
bindata.columns = bindata.columns.map('B{0}'.format)
res = pd.concat([df, bindata], axis=1).convert_objects(convert_numeric=True)
于 2013-08-03T16:32:04.767 に答える