5

皆さんこんにちは、

私は数年前から Stackoverflow を探していましたが、とても役に立ったので、以前は登録する必要がありませんでした :)

しかし、今日、Pandas と Quantities (unum または pint の可能性もあります) で Python を使用する際に問題が発生します。私は明確な投稿をするために最善を尽くしますが、それが私の最初の投稿であるため、何かが混乱している場合はお詫びし、見つけた間違いを修正しようとします :)


ソースからデータをインポートし、次のように Pandas データフレームを構築したいと考えています。

import pandas as pd
import quantities as pq

depth = [0.0,1.1,2.0] * pq.m
depth2 = [0,1,1.1,1.5,2] * pq.m

s1 = pd.DataFrame(
        {'depth' : [x for x in depth]},
        index = depth)

これは与える:

S1=
     depth
0.0  0.0 m
1.1  1.1 m
2.0  2.0 m

ここで、データを深さ 2 の値に拡張したいと考えています (明らかに、深さに対して深さを補間するポイントはありませんが、より複雑になる前のテストです)。

s2 = s1.reindex(depth2)

これは与える:

S2=
      depth
0.0   0.0 m
1.0   NaN
1.1   1.1 m
1.5   NaN
2.0   2.0 m

これまでのところ問題ありません。


しかし、欠損値を補間しようとすると、次のようになります。

s2['depth'].interpolate(method='values')

次のエラーが発生しました。

C:\Python27\lib\site-packages\numpy\lib\function_base.pyc in interp(x, xp, fp, left, right)
   1067         return compiled_interp([x], xp, fp, left, right).item()
   1068     else:
-> 1069         return compiled_interp(x, xp, fp, left, right)
  1070 
  1071 
TypeError: Cannot cast array data from dtype('O') to dtype('float64') according to the rule 'safe'

numpy からの補間がオブジェクトに対して機能しないことを理解しています。


しかし、単位を削除して欠損値を補間しようとすると、次のように機能します。

s3 = s2['depth'].astype(float).interpolate(method='values')

これは与える:

s3 = 
0.0   0
1.0   1
1.1   1.1
1.5   1.5
2.0   2
Name: depth, dtype: object

深度列の単位を戻すにはどうすればよいですか?

ユニットを元に戻すコツが見つかりません...

どんな助けでも大歓迎です。ありがとう

4

2 に答える 2

0

わかりました、解決策を見つけました。最善の解決策ではないかもしれませんが、私の問題では問題なく動作します:

import pandas as pd
import quantities as pq

def extendAndInterpolate(input, newIndex):
""" Function to extend a panda dataframe and interpolate
"""
output = pd.concat([input, pd.DataFrame(index=newIndex)], axis=1)

for col in output.columns:
    # (1) Try to retrieve the unit of the current column
    try:
        # if it succeeds, then store the unit
        unit = 1 * output[col][0].units    
    except Exception, e:
        # if it fails, which means that the column contains string
        # then return 1
        unit = 1

    # (2) Check the type of value.
    if isinstance(output[col][0], basestring):
        # if it's a string return the string and fill the missing cell with this string
        value = output[col].ffill()
    else:
        # if it's a value, to be able to interpolate, you need to:
        #   - (a) dump the unit with astype(float)
        #   - (b) interpolate the value
        #   - (c) add again the unit
        value = [x*unit for x in output[col].astype(float).interpolate(method='values')]
    #
    # (3) Returned the extended pandas table with the interpolated values    
    output[col] = pd.Series(value, index=output.index)
# Return the output dataframe
return output

それで:

depth = [0.0,1.1,2.0] * pq.m
depth2 = [0,1,1.1,1.5,2] * pq.m

s1 = pd.DataFrame(
        {'depth' : [x for x in depth]},
        index = depth)

s2 = extendAndInterpolate(s1, depth2)

結果:

s1
     depth
0.0  0.0 m
1.1  1.1 m
2.0  2.0 m

s2     
     depth
0.0  0.0 m
1.0  1.0 m
1.1  1.1 m
1.5  1.5 m
2.0  2.0 m

助けてくれてありがとう。

于 2013-10-15T12:07:34.557 に答える