5

次の形式で複素数の列を読み取る必要があります。

# index; (real part, imaginary part); (real part, imaginary part) 

  1              (1.2, 0.16)                  (2.8, 1.1)
  2              (2.85, 6.9)                  (5.8, 2.2)

NumPy は、区切り文字が 1 つしかないデータの列を読み取るのには優れているように見えますが、括弧はnumpy.loadtxt().

Python でファイルを読み取る賢い方法はありますか?それとも、ファイルを読み取ってかっこをすべて削除し、それを NumPy にフィードするのが最善ですか?

これは何千ものファイルに対して行う必要があるため、自動化された方法が必要ですが、NumPy ではこれができない可能性があります。

4

3 に答える 3

5

これは、@ Jeffの答えよりも直接的な方法で、にマップするloadtxtヘルパー関数を使用して、複雑な配列に直接ロードするように指示します:parse_pair(1.2,0.16)1.20+0.16j

>>> import re
>>> import numpy as np

>>> pair = re.compile(r'\(([^,\)]+),([^,\)]+)\)')
>>> def parse_pair(s):
...    return complex(*map(float, pair.match(s).groups()))

>>> s = '''1 (1.2,0.16) (2.8,1.1)
2 (2.85,6.9) (5.8,2.2)'''
>>> from cStringIO import StringIO
>>> f = StringIO(s)

>>> np.loadtxt(f, delimiter=' ', dtype=np.complex,
...            converters={1: parse_pair, 2: parse_pair})
array([[ 1.00+0.j  ,  1.20+0.16j,  2.80+1.1j ],
       [ 2.00+0.j  ,  2.85+6.9j ,  5.80+2.2j ]])

またはパンダで:

>>> import pandas as pd
>>> f.seek(0)
>>> pd.read_csv(f, delimiter=' ', index_col=0, names=['a', 'b'],
...             converters={1: parse_pair, 2: parse_pair})
             a           b
1  (1.2+0.16j)  (2.8+1.1j)
2  (2.85+6.9j)  (5.8+2.2j)
于 2013-05-21T00:38:26.120 に答える
4

この問題は pandas ではまだ解決されていないため、別の解決策を追加させてください。読み込んだDataFrame、ワンライナーで変更できます:

import pandas as pd

df = pd.read_csv('data.csv')
df = df.apply(lambda col: col.apply(lambda val: complex(val.strip('()'))))
于 2015-10-30T15:23:52.277 に答える
2

表示されているようにファイルに 5 列しかない場合は、変換用の正規表現を使用して pandas にフィードし、すべての行でかっこをコンマに置き換えることができます。その後、このSOの回答で提案されているようにそれらを組み合わせて、複素数を取得できます。

Pandas では、正規表現をそのメソッドに渡すことができるため、より簡単になりread_csvます。これにより、より明確なコードを記述し、このようなコンバーターを使用できます。numpy バ​​ージョンに対する利点は、区切り文字に正規表現を渡すことができることです。

import pandas as pd
from StringIO import StringIO
f_str = "1 (2, 3) (5, 6)\n2 (3, 4) (4, 8)\n3 (0.2, 0.5) (0.6, 0.1)"
f.seek(0)

def complex_converter(txt):
    txt = txt.strip("()").replace(", ", "+").replace("+-", "-") + "j"
    return complex(txt)

df = pd.read_csv(buf, delimiter=r" \(|\) \(", converters = {1: complex_converter, 2: complex_converter}, index_col=0)

編集:これを投稿する直前に@Dougalがこれを思いついたようです...実際には、複素数をどのように処理したいかによって異なります。reモジュールの明示的な使用を避けることができるのが好きです。

于 2013-05-21T00:20:51.717 に答える