2016-10-11 2 views
3

カテゴリと値を持つデータフレームがあります。値に最も近い各カテゴリの値を見つける必要があります。私は近いと思いますが、元のデータフレームにargsortの結果を適用すると、正しい結果を得られません。例えばPandasを使用して各フィルタの列内で最も近い値を特定します

、入力、出力、以下のコードで定義された場合にのみ(a, 1, True)(b, 2, True)(c, 2, True)を有するべきであり、他のすべてのisClosest Valuesは偽であるべきです。

複数の値が最も近い場合は、最初にマークされた値にする必要があります。

ここでは動作するコードはありますが、データフレームに正しく再適用することができません。私はいくつかの指針を愛するだろう。

df = pd.DataFrame() 
df['category'] = ['a', 'b', 'b', 'b', 'c', 'a', 'b', 'c', 'c', 'a'] 
df['values'] = [1, 2, 3, 4, 5, 4, 3, 2, 1, 0] 
df['isClosest'] = False 

uniqueCategories = df['category'].unique() 
for c in uniqueCategories: 
    filteredCategories = df[df['category']==c]  
    sortargs = (filteredCategories['value']-2.0).abs().argsort() 
    #how to use sortargs so that we set column in df isClosest=True if its the closest value in each category to 2.0? 

答えて

3

あなたは絶対差の列を作成することができます

df['dif'] = (df['values'] - 2).abs() 

df 
Out: 
    category values dif 
0  a  1 1 
1  b  2 0 
2  b  3 1 
3  b  4 2 
4  c  5 3 
5  a  4 2 
6  b  3 1 
7  c  2 0 
8  c  1 1 
9  a  0 2 

をし、各グループの最小値は、あなたが計算された差に等しいかどうかをチェックするためにgroupby.transformを使用します。

df['is_closest'] = df.groupby('category')['dif'].transform('min') == df['dif'] 

df 
Out: 
    category values dif is_closest 
0  a  1 1  True 
1  b  2 0  True 
2  b  3 1  False 
3  b  4 2  False 
4  c  5 3  False 
5  a  4 2  False 
6  b  3 1  False 
7  c  2 0  True 
8  c  1 1  False 
9  a  0 2  False 

df.groupby('category')['dif'].idxmin()には、各カテゴリに最も近い値のインデックスも表示されます。これをマッピングにも使用できます。割り当てのために

df.loc[df.groupby('category')['dif'].idxmin()] 
Out: 
    category values dif 
0  a  1 1 
1  b  2 0 
7  c  2 0 

:選択のため

df['is_closest'] = False 
df.loc[df.groupby('category')['dif'].idxmin(), 'is_closest'] = True 
df 
Out: 
    category values dif is_closest 
0  a  1 1  True 
1  b  2 0  True 
2  b  3 1  False 
3  b  4 2  False 
4  c  5 3  False 
5  a  4 2  False 
6  b  3 1  False 
7  c  2 0  True 
8  c  1 1  False 
9  a  0 2  False 

これらのアプローチの違いは、あなたが違いに対する平等をチェックすると、あなたはネクタイの場合は全ての行のための真になるだろうということです。ただし、idxminを指定すると、最初のオカレンスに対してTrueが返されます(グループごとに1つだけ)。

3
DataFrameGroupBy.idxmin

ソリューション - グループあたりの極小値のインデックスを取得し、その後、カラムisClosestIndex.isinによってブールマスクを割り当てます。

idx = (df['values'] - 2).abs().groupby([df['category']]).idxmin() 
print (idx) 
category 
a 0 
b 1 
c 7 
Name: values, dtype: int64 

df['isClosest'] = df.index.isin(idx) 
print (df) 
    category values isClosest 
0  a  1  True 
1  b  2  True 
2  b  3  False 
3  b  4  False 
4  c  5  False 
5  a  4  False 
6  b  3  False 
7  c  2  True 
8  c  1  False 
9  a  0  False 
関連する問題