Identifying closest value in a column for each filter using Pandas
<p>I have a data frame with categories and values.  I need to find the value in each category closest to a value.  I think I'm close but I can't really get the right output when applying the results of argsort to the original dataframe.</p>

<p>For example, if the input was defined in the code below the output should have only <code>(a, 1, True)</code>, <code>(b, 2, True)</code>, <code>(c, 2, True)</code> and all other isClosest <code>Values</code> should be False.</p>

<p>If multiple values are closest then it should be the first value listed marked.</p>

<p>Here is the code I have which works but I can't get it to reapply to the dataframe correctly.  I would love some pointers.</p>

<pre><code>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?
</code></pre>

<p>Solution with <a href="http://pandas.pydata.org/pandas-docs/stable/generated/pandas.core.groupby.DataFrameGroupBy.idxmin.html" rel="nofollow"><code>DataFrameGroupBy.idxmin</code></a> - get indexes of minimal values per group and then assign boolean mask by <a href="http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Index.isin.html" rel="nofollow"><code>Index.isin</code></a> to column <code>isClosest</code>:</p>

<pre><code>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
</code></pre>

python pandas group-by boolean closest