2017-09-19 10 views
3

私はGroupByの周りを回っていますが、まだ助けが必要です。私はオブジェクトのグループ番号、いくつかのパラメータRと球座標RADecを与えて、Groupという列のDataFrameを持っているとしましょう。私は(Rが負であるため、又は最大絶対値)が最小Rと、ワン、すなわち、各グループは、「明るい」オブジェクトを含む内蔵選択したいPandas DataFrameで複雑なサブセットを構築する

df = pd.DataFrame({ 
    'R' : (-21.0,-21.5,-22.1,-23.7,-23.8,-20.4,-21.8,-19.3,-22.5,-24.7,-19.9), 
    'RA': (154.362789,154.409301,154.419191,154.474165,154.424842,162.568516,8.355454,8.346812,8.728223,8.759622,8.799796), 
    'Dec': (-0.495605,-0.453085,-0.481657,-0.614827,-0.584243,8.214719,8.355454,8.346812,8.728223,8.759622,8.799796), 
    'Group': (1,1,1,1,1,2,2,2,2,2,2) 
}) 

と:ここで模擬データフレームでありますグループの3つの最も近いオブジェクト(したがって、私は各グループに4つのオブジェクトを保持します - 必要であれば4つのオブジェクトより小さいグループは存在しません)。

は、我々は次のような機能が定義されていることを、ここで想定しています

#deg to rad 
def d2r(x): 
    return x * np.pi/180.0 

#rad to deg 
def r2d(x): 
    return x * 180.0/np.pi 

#Computes separation on a sphere 
def calc_sep(phi1,theta1,phi2,theta2): 
    return np.arccos(np.sin(theta1)*np.sin(theta2) + 
        np.cos(theta1)*np.cos(theta2)*np.cos(phi2 - phi1)) 

と2つのオブジェクト間のその分離はように第一の目的のためにRAとしてRA1で、r2d(calc_sep(RA1,Dec1,RA2,Dec2))によって与えられ、。あなたがここに何ができるか

私はこれを達成するためにGroupByを使用する方法を見つけ出すことはできません...

+0

期待するものの例を挙げることができますか?グループ内のオブジェクトをソートしますか? – igrinis

答えて

2

は、各「サブフレーム」(各グループ)に適用されます、より具体的なヘルパー関数を構築しています。

GroupByは本当にただ(グループID、データフレーム)のペア​​のイテレータのようなものを作成する施設である、とあなたが.groupby().applyを呼び出すときに、関数は、これらのそれぞれに適用されます。 (それはあなたが興味を持っている場合は内部にいくつかの詳細についてhereを参照してください、詳細の多くの上に釉薬。)

だからあなたの3 numpyのベースの関数を定義した後、また定義:

def sep_df(df, keep=3): 
    min_r = df.loc[df.R.argmin()] 
    RA1, Dec1 = min_r.RA, min_r.Dec 
    sep = r2d(calc_sep(RA1,Dec1,df['RA'], df['Dec'])) 
    idx = sep.nsmallest(keep+1).index 
    return df.loc[idx] 

をそれからちょうど適用します最初のインデックスレベルがグループであるMultiIndex DataFrameを取得します。散在するいくつかのコメントで

print(df.groupby('Group').apply(sep_df)) 
       Dec Group  R   RA 
Group          
1  3 -0.61483  1 -23.7 154.47416 
     2 -0.48166  1 -22.1 154.41919 
     0 -0.49561  1 -21.0 154.36279 
     4 -0.58424  1 -23.8 154.42484 
2  8 8.72822  2 -22.5 8.72822 
     10 8.79980  2 -19.9 8.79980 
     6 8.35545  2 -21.8 8.35545 
     9 8.75962  2 -24.7 8.75962 

:スピードについては

def sep_df(df, keep=3): 
    # Applied to each sub-Dataframe (this is what GroupBy does under the hood) 

    # Get RA and Dec values at minimum R 
    min_r = df.loc[df.R.argmin()] # Series - row at which R is minimum 
    RA1, Dec1 = min_r.RA, min_r.Dec # Relevant 2 scalars within this row 

    # Calculate separation for each pair including minimum R row 
    # The result is a series of separations, same length as `df` 
    sep = r2d(calc_sep(RA1,Dec1,df['RA'], df['Dec'])) 

    # Get index values of `keep` (default 3) smallest results 
    # Retain `keep+1` values because one will be the minimum R 
    # row where separation=0 
    idx = sep.nsmallest(keep+1).index 

    # Restrict the result to those 3 index labels + your minimum R 
    return df.loc[idx] 

consider passing sort=False GROUPBYの結果はまだあなたのために動作するかどうか。

+0

すごい!それは私が探していたものです。ありがとう。私はそれがどのように機能するのか理解し始めます。利用可能な場合は賞金を授与します(22時間後)。ちょうど質問:私はそれを行うとき、私は 'RuntimeWarning:arccosで遭遇する値が無効です '、どの行が問題を引き起こすかをどのように知るのですか? – Matt

+1

私は考えることができるいくつかの理由があります:1つは、実際にはデータが文字列として表現されていてはならない場合です。 'df.dtypes'を試してみるか、[this](https://stackoverflow.com/questions/26660313/pandas-location-of-a-with-error)を見てください。 - >次に 'pd.to_numeric'で数値に変換します。もう1つの疑問は、arccos(1.041516417)は未定義ですが、それが問題であるかどうかは疑問です。あなたの完全なデータセットを見ずに言うのは難しいです。 –

+0

あなたの答えをありがとう。いいえ、RAとDECはfloat64です。はい、コサインは常に-1と1の間にあるため、arccos(1.041516417)は未定義ですが、なぜこの値が発生しますか? – Matt

2

各グループに対して「最も明るい」オブジェクトを含む選択を作成したいと思います...グループ

ステップ1の3つの最も近いオブジェクト:

は、2つのフレームにマージ:

maxR = df.sort_values('R').groupby('Group')['Group', 'Dec', 'RA'].head(1) 

ステップ2各グループ内の最も明るいオブジェクトのデータフレームを作成しますGroup &分離を計算する

merged = df.merge(maxR, on = 'Group', suffixes=['', '_max']) 
merged['sep'] = merged.apply(
    lambda x: r2d(calc_sep(x.RA, x.Dec, x.RA_max, x.Dec_max)), 
    axis=1 
) 

ステップ3:

注文データフレーム、'Group'によって基、(オプション)中間フィールドを破棄 &、各グループからの最初の4行

finaldf = merged.sort_values(['Group', 'sep'], ascending=[1,1] 
).groupby('Group')[df.columns].head(4) 

はあなたと次のデータフレームを生成し取りますサンプルデータ:

  Dec Group  R   RA 
4 -0.584243  1 -23.8 154.424842 
3 -0.614827  1 -23.7 154.474165 
2 -0.481657  1 -22.1 154.419191 
0 -0.495605  1 -21.0 154.362789 
9 8.759622  2 -24.7 8.759622 
8 8.728223  2 -22.5 8.728223 
10 8.799796  2 -19.9 8.799796 
6 8.355454  2 -21.8 8.355454 
+0

非常に明確です、ありがとうございます! :) – Matt

関連する問題