2017-05-04 5 views
2

私は、次のデータフレームを持っている:パンダのデータフレームの選択された行と列にのみ関数を適用するにはどうすればいいですか?

 id  subid  a 
    1 1   1   2 
    2 1   1   10 
    3 1   1   20 
    4 1   2   30 
    5 1   2   35 
    6 1   2   36 
    7 1   2   40 
    8 2   2   20 
    9 2   2   29 
    10 2   2   30 

私はコラム「A」の例パンダ​​の差分()関数のために言い適用したいのですが、「ID」または「サブID」のいずれかである時はいつでも機能を再適用する必要があります変更され、新しい列に値を格納する必要があります。

以下は私が期待しているdfです。

 id  subid  a  difference 
    1 1   1   2  NaN 
    2 1   1   10  8 
    3 1   1   20  10 
    4 1   2   30  NaN 
    5 1   2   35  5 
    6 1   2   36  1 
    7 1   2   40  4 
    8 2   2   20  NaN 
    9 2   2   29  9 
    10 2   2   30  1 

それが行4で観察することができ、および行8「ID」または「サブID」のいずれかが変化しているようなので、NaN値が存在し、差分が連続する行で計算されます。

は明らかに列全体ではなく、予想される方法に適用される

df["difference"] = df["a"].diff() 

を使用しました。私はgroupbyを使ってみましたが、何とか余分な行を与えています。

事前にお寄せいただきありがとうございます。

答えて

2

これはトリッキーなものです。あなたの正確な言い回しによると、'id'または'subid'のいずれかのポイントがリセットされます。それはたとえ彼らが前後に変化したとしても意味します。

また、diffの計算では、groupbyのコンテキスト内で計算しても差はありませんので、状況が変わったときに計算してマスクします。

i = df.id.values 
s = df.subid.values 
i_chg = np.append(False, i[:-1] != i[1:]) 
s_chg = np.append(False, s[:-1] != s[1:]) 

df.assign(difference=df.a.diff().mask(i_chg | s_chg)) 

    id subid a difference 
1 1  1 2   NaN 
2 1  1 10   8.0 
3 1  1 20  10.0 
4 1  2 30   NaN 
5 1  2 35   5.0 
6 1  2 36   1.0 
7 1  2 40   4.0 
8 2  1 20   NaN 
9 2  1 29   9.0 
10 2  1 30   1.0 
+0

はとてもありがとう11行目を持っている場合、これはおそらく動作しません。多く、これはうまくいった。 – Liza

+0

ええ、そうです。 – Liza

+0

あなたはちょうどこの[リンク](http://stackoverflow.com/questions/14631776/calculate-turning-points-pivot-points-in-trajectory-path)を見てみることができます私は検証された答えを実装しようとしていますdfで図示されているのは、座標がnp配列である単一の軌道上にあり、数千の軌道を持つdfを持ち、それぞれが(x、y)座標を持たず、 "id"と "subid"コンボ(上記のように)。 DFに「方向」と「角度」機能を適用する方法を教えてください。それとも私はこれについて質問を作成したいですか? – Liza

2

はこれを試してみてください。

In [97]: df['difference'] = df.groupby(['id','subid'])['a'].diff() 

In [98]: df 
Out[98]: 
    id subid a difference 
1 1  1 2   NaN 
2 1  1 10   8.0 
3 1  1 20  10.0 
4 1  2 30   NaN 
5 1  2 35   5.0 
6 1  2 36   1.0 
7 1  2 40   4.0 
8 2  1 20   NaN 
9 2  1 29   9.0 
10 2  1 30   1.0 
+0

次のような'11 1 1 2' – Allen

2

セットアップ

df = pd.DataFrame({'a': {1: 2, 2: 10, 3: 20, 4: 30, 5: 35, 6: 36, 7: 40, 8: 20, 9: 29, 10: 30}, 
'id': {1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1, 8: 2, 9: 2, 10: 2}, 
'subid': {1: 1, 2: 1, 3: 1, 4: 2, 5: 2, 6: 2, 7: 2, 8: 1, 9: 1, 10: 1}}) 

ソリューション

#Check for each row if the id-subid pair has changed with previous row and then calculate diff accordingly  
df['difference'] = df.apply(lambda x: x.a - df.ix[x.name-1].a 
    if (x.name>1 and x[['id','subid']].equals(df.ix[x.name-1][['id','subid']])) 
    else np.nan, axis=1) 

df 
Out[368]: 
    a id subid difference 
1 2 1  1   NaN 
2 10 1  1   8.0 
3 20 1  1  10.0 
4 30 1  2   NaN 
5 35 1  2   5.0 
6 36 1  2   1.0 
7 40 1  2   4.0 
8 20 2  1   NaN 
9 29 2  1   9.0 
10 30 2  1   1.0 
関連する問題