4

別の列の場所の値がその下の行で変更されたかどうかを表す pandas データフレームがあります。例として、

2013-02-05 19:45:00   (39.94, -86.159)     True
2013-02-05 19:50:00   (39.94, -86.159)     True
2013-02-05 19:55:00   (39.94, -86.159)    False
2013-02-05 20:00:00  (39.777, -85.995)    False
2013-02-05 20:05:00  (39.775, -85.978)     True
2013-02-05 20:10:00  (39.775, -85.978)     True
2013-02-05 20:15:00  (39.775, -85.978)    False
2013-02-05 20:20:00   (39.94, -86.159)     True
2013-02-05 20:30:00   (39.94, -86.159)    False

だから、私がしたいのは、このデータフレームを行ごとに調べて、行をチェックすることFalseです. そして、(別の列を追加することもできます)その場所で費やされた合計「連続」時間があります。上記の例のように、同じ場所を再度訪れることができます。その場合は別途条件とさせていただきます。したがって、上記の例では、次のようになります。

2013-02-05 19:45:00   (39.94, -86.159)     True    0
2013-02-05 19:50:00   (39.94, -86.159)     True    0
2013-02-05 19:55:00   (39.94, -86.159)    False   15
2013-02-05 20:00:00  (39.777, -85.995)    False    5  
2013-02-05 20:05:00  (39.775, -85.978)     True    0
2013-02-05 20:10:00  (39.775, -85.978)     True    0
2013-02-05 20:15:00  (39.775, -85.978)    False   15
2013-02-05 20:20:00   (39.94, -86.159)     True    0 
2013-02-05 20:25:00   (39.94, -86.159)    False   10

次に、1 日あたりの hist() 関数の使用に費やされたこれらの「継続的な」時間のヒストグラムをプロットします。データフレームを反復処理して、最初のデータフレームから 2 番目のデータフレームを取得するにはどうすればよいですか? 私はpythonとpandasが初めてで、実際のデータファイルは巨大なので、かなり効率的なものが必要です。

4

2 に答える 2

7

ここに別のテイクがあります

df['group'] = (df.condition == False).astype('int').cumsum().shift(1).fillna(0)

df
             date    long     lat condition  group
2/5/2013 19:45:00  39.940 -86.159      True      0
2/5/2013 19:50:00  39.940 -86.159      True      0
2/5/2013 19:55:00  39.940 -86.159     False      0
2/5/2013 20:00:00  39.777 -85.995     False      1
2/5/2013 20:05:00  39.775 -85.978      True      2
2/5/2013 20:10:00  39.775 -85.978      True      2
2/5/2013 20:15:00  39.775 -85.978     False      2
2/5/2013 20:20:00  39.940 -86.159      True      3
2/5/2013 20:25:00  39.940 -86.159     False      3

df['result'] = df.groupby(['group']).date.transform(lambda sdf: 5 *len(sdf))

df
             date    long     lat condition  group result
2/5/2013 19:45:00  39.940 -86.159      True      0     15
2/5/2013 19:50:00  39.940 -86.159      True      0     15
2/5/2013 19:55:00  39.940 -86.159     False      0     15
2/5/2013 20:00:00  39.777 -85.995     False      1      5
2/5/2013 20:05:00  39.775 -85.978      True      2     15
2/5/2013 20:10:00  39.775 -85.978      True      2     15
2/5/2013 20:15:00  39.775 -85.978     False      2     15
2/5/2013 20:20:00  39.940 -86.159      True      3     10
2/5/2013 20:25:00  39.940 -86.159     False      3     10
于 2013-03-28T17:54:13.810 に答える
4

0.11-dev が必要です。これはあなたが探しているものをあなたに与えると思います。このセクションを参照してください: http://pandas.pydata.org/pandas-docs/dev/timeseries.html#time-deltas詳細については、timedeltas が pandas がサポートしている新しいデータであるためです。

あなたのデータは次のとおりです(便宜上、経度と経度を分けました。重要なことは、条件列がブール値であることです)

In [137]: df = pd.read_csv(StringIO.StringIO(data),index_col=0,parse_dates=True)

In [138]: df
Out[138]: 
               date    long       lat condition
2013-02-05 19:45:00  39.940   -86.159      True
2013-02-05 19:50:00  39.940   -86.159      True
2013-02-05 19:55:00  39.940   -86.159     False
2013-02-05 20:00:00  39.777   -85.995     False
2013-02-05 20:05:00  39.775   -85.978      True
2013-02-05 20:10:00  39.775   -85.978      True
2013-02-05 20:15:00  39.775   -85.978     False
2013-02-05 20:20:00  39.940   -86.159      True
2013-02-05 20:25:00  39.940   -86.159     False

In [139]: df.dtypes
Out[139]: 
date         float64
long lat     float64
condition       bool
dtype: object

インデックスであるいくつかの日付列を作成します (これらは datetime64[ns] dtype です)。

In [140]: df['date'] = df.index   
In [141]: df['rdate'] = df.index

False の rdate 列を NaT に設定します (np.nan は NaT に変換されます)。

In [142]: df.loc[~df['condition'],'rdate'] = np.nan

前の値から NaT を順方向に埋める

In [143]: df['rdate'] = df['rdate'].ffill()

日付から rdate を減算すると、時差の timedelta64[ns] タイプの列が生成されます

In [144]: df['diff'] = df['date']-df['rdate']

In [151]: df
Out[151]: 
                                   date  long lat condition               rdate  \
2013-02-05 19:45:00 2013-02-05 19:45:00   -86.159      True 2013-02-05 19:45:00   
2013-02-05 19:50:00 2013-02-05 19:50:00   -86.159      True 2013-02-05 19:50:00   
2013-02-05 19:55:00 2013-02-05 19:55:00   -86.159     False 2013-02-05 19:50:00   
2013-02-05 20:00:00 2013-02-05 20:00:00   -85.995     False 2013-02-05 19:50:00   
2013-02-05 20:05:00 2013-02-05 20:05:00   -85.978      True 2013-02-05 20:05:00   
2013-02-05 20:10:00 2013-02-05 20:10:00   -85.978      True 2013-02-05 20:10:00   
2013-02-05 20:15:00 2013-02-05 20:15:00   -85.978     False 2013-02-05 20:10:00   
2013-02-05 20:20:00 2013-02-05 20:20:00   -86.159      True 2013-02-05 20:20:00   
2013-02-05 20:25:00 2013-02-05 20:25:00   -86.159     False 2013-02-05 20:20:00   

                        diff  
2013-02-05 19:45:00 00:00:00  
2013-02-05 19:50:00 00:00:00  
2013-02-05 19:55:00 00:05:00  
2013-02-05 20:00:00 00:10:00  
2013-02-05 20:05:00 00:00:00  
2013-02-05 20:10:00 00:00:00  
2013-02-05 20:15:00 00:05:00  
2013-02-05 20:20:00 00:00:00  
2013-02-05 20:25:00 00:05:00  

diff 列は現在 timedelta64[ns] であるため、分単位の整数が必要です (参考までに、パンダには日付のタイムスタンプに似たスカラー型 Timedelta がないため、これは少し不格好です)。

(また、この rdate シリーズで、入力する前に shift() を実行する必要があるかもしれません。どこかで 1 ずれていると思います)...しかし、これがアイデアです

In [175]: df['diff'].map(lambda x: x.item().seconds/60)
Out[175]: 
2013-02-05 19:45:00     0
2013-02-05 19:50:00     0
2013-02-05 19:55:00     5
2013-02-05 20:00:00    10
2013-02-05 20:05:00     0
2013-02-05 20:10:00     0
2013-02-05 20:15:00     5
2013-02-05 20:20:00     0
2013-02-05 20:25:00     5
于 2013-03-28T14:44:39.407 に答える