2

私は、次のような .csv ファイルがある python プロジェクトに取り組んでいます。

freq,ae,cl,ota
825,1,2,3
835,4,5,6
850,10,11,12
880,22,23,24
910,46,47,48
960,94,95,96
1575,190,191,192
1710,382,383,384
1750,766,767,768

実行時にファイルからデータをすばやく取得する必要があります。
例を挙げると:

私は 880MHz の周波数でサンプリングしています。サンプルに対していくつかの計算を行い、.csv ファイルの 880 行のデータを利用したいと考えています。

freq コロンをインデックスとして使用してこれを行い、サンプリング周波数を使用してデータを取得しましたが、注意が必要なのは、900MHz でサンプリングするとエラーが発生することです。上下の最も近いデータ、この場合は 880 と 910 を取りたいと思います。これらの行から、データを使用して、900MHz でのデータがどのように見えるかを線形化して推定します。

私の主な問題は、データをすばやく検索する方法です.完全に一致するものが存在しない場合、最も近い2つの行を取得する方法は?

4

3 に答える 3

3

前の行/シリーズと後の行を取る

In [11]: before, after = df1.loc[:900].iloc[-1], df1.loc[900:].iloc[0]

In [12]: before
Out[12]:
ae     22
cl     23
ota    24
Name: 880, dtype: int64

In [13]: after
Out[13]:
ae     46
cl     47
ota    48
Name: 910, dtype: int64

空の行を中央に配置して補間します (編集: デフォルトの補間では 2 つの平均を取るだけなので、 を設定する必要がありますmethod='values'):

In [14]: sandwich = pd.DataFrame([before, pd.Series(name=900), after])

In [15]: sandwich
Out[15]:
     ae  cl  ota
880  22  23   24
900 NaN NaN  NaN
910  46  47   48

In [16]: sandwich.apply(apply(lambda col: col.interpolate(method='values'))
Out[16]:
     ae  cl  ota
880  22  23   24
900  38  39   40
910  46  47   48

In [17]: sandwich.apply(apply(lambda col: col.interpolate(method='values')).loc[900]
Out[17]:
ae     38
cl     39
ota    40
Name: 900, dtype: float64

ノート:

df1 = pd.read_csv(csv_location).set_index('freq')

そして、これをある種の関数でラップすることができます:

def interpolate_for_me(df, n):
    if n in df.index:
        return df.loc[n]
    before, after = df1.loc[:n].iloc[-1], df1.loc[n:].iloc[0]
    sandwich = pd.DataFrame([before, pd.Series(name=n), after])
    return sandwich.apply(lambda col: col.interpolate(method='values')).loc[n]
于 2013-05-17T17:57:03.777 に答える
0

bisectモジュールは、ソートされたシーケンス内で二等分を実行します。

于 2013-05-17T17:26:04.253 に答える
0
import csv
import bisect

def interpolate_data(data, value):
    # check if value is in range of the data.
    if data[0][0] <= value <= data[-1][0]: 
        pos = bisect.bisect([x[0] for x in data], value)
        if data[pos][0] == value:
            return data[pos][0]
        else:
            prev = data[pos-1]
            curr = data[pos]
            factor = 1+(value-prev[0])/(curr[0]-prev[0])
            return [value]+[x*factor for x in prev[1:]]

with open("data.csv", "rb") as csvfile:
    f = csv.reader(csvfile)
    f.next() # remove the header
    data = [[float(x) for x in row] for row in f] # convert all to float

# test value 1200:
interpolate_data(data, 1200)
# = [1200, 130.6829268292683, 132.0731707317073, 133.46341463414632]

私にとってはうまくいき、かなり理解しやすいです。

于 2013-05-17T18:16:13.180 に答える