7

私はパンダが初めてで、奇妙なフォーマットのファイルを DataFrame に読み込もうとしています。元のファイルは次のようになります。

; No   Time   Date  MoistAve  MatTemp  TDRConduct  TDRAve  DeltaCount  tpAve  Moist1  Moist2  Moist3  Moist4  TDR1  TDR2  TDR3  TDR4
1  11:38:17   11.07.2012  11.37  48.20  5.15  88.87  15  344.50  11.84  11.35  11.59  15.25  89.0  89.0  89.0  88.0
2  11:38:18   11.07.2012  11.44  48.20  5.13  88.88  2  346.22  12.08  11.83  -1.00  -1.00  89.0  89.0  -1.0  -1.0
3  11:38:19   11.07.2012  11.10  48.20  4.96  89.00  3  337.84  11.83  11.59  10.62  -1.00  89.0  89.0  89.0  -1.0
4  11:38:19   11.07.2012  11.82  48.20  5.54  88.60  3  355.92  11.10  13.54  12.32  -1.00  89.0  88.0  88.0  -1.0

以下を使用して、同様に構造化された DataFrame を取得できました。

In [42]: date_spec = {'FetchTime': [1, 2]}

In [43]: df = pd.read_csv('MeasureCK32450-20120711114050.mck', header=7, sep='\s\s+',
                          parse_dates=date_spec, na_values=['-1.0', '-1.00'])

In [44]: df
Out[52]: 
               FetchTime  ; No  MoistAve  MatTemp  TDRConduct  TDRAve  DeltaCount   tpAve  Moist1  Moist2  Moist3  Moist4  TDR1  TDR2  TDR3  TDR4
0    2012-11-07 11:38:17     1     11.37     48.2        5.15   88.87          15  344.50   11.84   11.35   11.59   15.25    89    89    89    88
1    2012-11-07 11:38:18     2     11.44     48.2        5.13   88.88           2  346.22   12.08   11.83     NaN     NaN    89    89   NaN   NaN
2    2012-11-07 11:38:19     3     11.10     48.2        4.96   89.00           3  337.84   11.83   11.59   10.62     NaN    89    89    89   NaN
3    2012-11-07 11:38:19     4     11.82     48.2        5.54   88.60           3  355.92   11.10   13.54   12.32     NaN    89    88    88   NaN

しかし今、この DataFrame の各行を展開する必要があります

  .... Moist1  Moist2  Moist3  Moist4  TDR1  TDR2  TDR3  TDR4
1 ....  11.84   11.35   11.59   15.25    89    89    89    88
2 ....  12.08   11.83     NaN     NaN    89    89   NaN   NaN

4 行に分割 (3 つのインデックス No、FetchTime、および MeasureNo):

                                  .... Moist  TDR
No           FetchTime  MeasureNo
 0 2012-11-07 11:38:17          1 .... 11.84   89 # from line 1, Moist1 and TDR1
 1                              2 .... 11.35   89 # from line 1, Moist2 and TDR2
 2                              3 .... 11.59   89 # from line 1, Moist3 and TDR3
 3                              4 .... 15.25   88 # from line 1, Moist4 and TDR4
 4 2012-11-07 11:38:18          1 .... 12.08   89 # from line 2, Moist1 and TDR1
 5                              2 .... 11.83   89 # from line 2, Moist2 and TDR2
 6                              3 ....   NaN  NaN # from line 2, Moist3 and TDR3
 7                              4 ....   NaN  NaN # from line 2, Moist4 and TDR4

他の列と最も重要な項目を保持し、エントリの順序を保持します。各行を反復処理できることはわかってfor row in df.iterrows(): ...いますが、これはあまり高速ではありません。私の最初のアプローチはこれでした:

In [54]: data = []
In [55]: for d in range(1,5):
....:     temp = df.ix[:, ['FetchTime', 'MoistAve', 'MatTemp', 'TDRConduct', 'TDRAve', 'DeltaCount', 'tpAve', 'Moist%d' % d, 'TDR%d' % d]]
....:     temp.columns = ['FetchTime', 'MoistAve', 'MatTemp', 'TDRConduct', 'TDRAve', 'DeltaCount', 'tpAve', 'RawMoist', 'RawTDR']
....:     temp['MeasureNo'] = d
....:     data.append(temp)
....:      
In [56]: test = pd.concat(data, ignore_index=True)
In [62]: test.head()
Out[62]: 
             FetchTime  MoistAve  MatTemp  TDRConduct  TDRAve  DeltaCount   tpAve  RawMoist  RawTDR  MeasureNo
0  2012-11-07 11:38:17     11.37     48.2        5.15   88.87          15  344.50     11.84      89          1
1  2012-11-07 11:38:18     11.44     48.2        5.13   88.88           2  346.22     12.08      89          1
2  2012-11-07 11:38:19     11.10     48.2        4.96   89.00           3  337.84     11.83      89          1
3  2012-11-07 11:38:19     11.82     48.2        5.54   88.60           3  355.92     11.10      89          1
4  2012-11-07 11:38:20     12.61     48.2        5.87   88.38           3  375.72     12.80      89          1

しかし、必要な順序を取得するために連結に影響を与える方法がわかりません...必要な結果のDataFrameを取得する別の方法はありますか?

4

2 に答える 2

1

これは、numpyの繰り返しと配列のインデックス付けに基づいてスタック解除された値を作成し、pandasのマージを使用して連結された結果を出力するソリューションです。

まず、データのサンプルをDataFrameにロードします(read_csvの引数を少し変更しました)。

from cStringIO import StringIO

data = """; No   Time   Date  MoistAve  MatTemp  TDRConduct  TDRAve  DeltaCount  tpAve  Moist1  Moist2  Moist3  Moist4  TDR1  TDR2  TDR3  TDR4
1  11:38:17   11.07.2012  11.37  48.20  5.15  88.87  15  344.50  11.84  11.35  11.59  15.25  89.0  89.0  89.0  88.0
2  11:38:18   11.07.2012  11.44  48.20  5.13  88.88  2  346.22  12.08  11.83  -1.00  -1.00  89.0  89.0  -1.0  -1.0
3  11:38:19   11.07.2012  11.10  48.20  4.96  89.00  3  337.84  11.83  11.59  10.62  -1.00  89.0  89.0  89.0  -1.0
4  11:38:19   11.07.2012  11.82  48.20  5.54  88.60  3  355.92  11.10  13.54  12.32  -1.00  89.0  88.0  88.0  -1.0
"""

date_spec = {'FetchTime': [1, 2]}
df = pd.read_csv(StringIO(data), header=0, sep='\s\s+',parse_dates=date_spec, na_values=['-1.0', '-1.00'])

次に、TDRのデスタックされたベクトルを構築し、元のデータフレームとマージします

stacked_col_names = ['TDR1','TDR2','TDR3','TDR4']

repeated_row_indexes = np.repeat(np.arange(df.shape[0]),4)
repeated_col_indexes = [np.where(df.columns == c)[0][0] for c in stacked_col_names]

destacked_tdrs = pd.DataFrame(data=df.values[repeated_row_indexes,repeated_col_indexes],index=df.index[repeated_row_indexes],columns=['TDR'])

ouput = pd.merge(left_index = True, right_index = True, left = df, right = destacked_tdrs)

目的の出力で:

output.ix[:,['TDR1','TDR2','TDR3','TDR4','TDR']]

   TDR1  TDR2  TDR3  TDR4  TDR
0    89    89    89    88   89
0    89    89    89    88   89
0    89    89    89    88   89
0    89    89    89    88   88
1    89    89   NaN   NaN   89
1    89    89   NaN   NaN   89
1    89    89   NaN   NaN  NaN
1    89    89   NaN   NaN  NaN
2    89    89    89   NaN   89
2    89    89    89   NaN   89
2    89    89    89   NaN   89
2    89    89    89   NaN  NaN
3    89    88    88   NaN   89
3    89    88    88   NaN   88
3    89    88    88   NaN   88
3    89    88    88   NaN  NaN
于 2013-03-04T10:17:28.040 に答える
0

これにより、「i」から始まる test の 4 行目ごとに次のようになります。

test.ix[i::4] 

上記と同じ基本ループを使用して、上記のコードを実行した後、0 から 3 で始まる 4 行ごとのセットを追加するだけです。

data = []    
for i in range(0,3:):     
    temp = test.ix[i::4] 
    data.append(temp)
test2 = pd.concat(data,ignore_index=True)

更新: 必要なのは 4 行ごとではなく、m 行ごとであることがわかりました。したがって、これは上記のループの提案にすぎません。ごめん。

更新 2: そうではないかもしれません。concatenate が希望する順序を返さない場合でも、concatenate が返すものは希望するものへの固定マッピングを持っているという事実を利用できます。d はタイムスタンプあたりの行数、m はタイムスタンプの数です。

次のようにテストからの行が必要なようです: [0,m,2m,3m,1,m+1,2m+1,3m+1,2,m+2,2m+2,3m+2,.. .,m-1,2m-1,3m-1,4m-1]

そのインデックスのリストを生成するもっと良い方法があると確信していますが、これは私にとってはうまくいきました

d = 4
m = 10
small = (np.arange(0,m).reshape(m,1).repeat(d,1).T.reshape(-1,1))
shifter = (np.arange(0,d).repeat(m).reshape(-1,1).T * m) 
NewIndex = (shifter.reshape(d,-1) + small.reshape(d,-1)).T.reshape(-1,1)
NewIndex = NewIndex.reshape(-1)
test = test.ix[NewIndex]
于 2012-12-09T17:57:59.770 に答える