Pandas groupby:在基于Pandas groupby组中另一列中的数据选择行之后如何选择相邻列数据?

时间:2019-02-21 17:38:12

标签: python pandas dataframe pandas-groupby

我有一个数据库,如下所示。对于每个日期,都有持续时间条目(每个日期1-20),其中列出了每个持续时间的项目(100s)。每个项目在相邻列中都有几个关联的数据点,包括标识符。对于每个日期,我想选择最长的持续时间。然后,我想找到一个值最接近给定输入值的项目。然后,我想获取该项目的ID,以便能够在数据库中跟踪该项目的值。

Index Date      Duration Item   Value  ID
0     1/1/2018     30     100      4    a
1     1/1/2018     30     200      8    b
2     1/1/2018     30     300     20    c
3     1/1/2018     60     100      9    d
4     1/1/2018     60     200     19    e
5     1/1/2018     60     300     33    f
6     1/1/2018     60     400     50    g
7     1/2/2018     31     100      3    a
8     1/2/2018     31     200      7    b
9     1/2/2018     31     300     20    c
10    1/2/2018     61     100      8    d
11    1/2/2018     61     200     17    e
12    1/2/2018     61     300     30    f

我认为pandas groupby函数对于创建日期/持续时间组非常理想:

df = df.groupby('Date')['Duration'].max()   #creates the correct groups of max duration for each date

没有groupby,可以通过找到正确的行来获取数据,例如:

row = df['ID'].index(df['Value'] - target_value).abs().argsort()[:1]]
id = df.loc[row, 'ID']

但是在分组群组中不起作用。我试图通过其他熊猫操作来解决此问题,但是在选择具有正确值的项目后无法弄清楚如何获取ID数据。 SO上有很多关于在pandas.groupby之后提取特定列中的数据(或将函数应用于特定列中的数据)的问题,但是在选择相邻列中的数据时我没有发现任何问题。如果您能指出正确的方向,我将不胜感激。

3 个答案:

答案 0 :(得分:0)

我希望我能正确理解您,可能会有一种更简单的方法,但这是我的想法:

data = [['1/1/2018' ,    30  ,   100    ,  4   , 'a'],
    ['1/1/2018'  ,    30 ,    200  ,    8 ,   'b'],
    ['1/1/2018'  ,   30   ,  300  ,  20  , 'c'],
    ['1/1/2018'  ,   60   ,  100     , 9   , 'd'],
    ['1/1/2018'   ,   60   ,  200     ,19  ,  'e'],
   ['1/1/2018'  ,   60   ,  300     ,33  ,  'f'],
   ['1/1/2018'   ,   60   ,  400     ,50  ,  'g'],
   ['1/2/2018'  ,   31   ,  100     , 3  ,  'a'],
   ['1/2/2018'   ,   31   ,  200    ,  7  ,  'b'],
  ['1/2/2018'  ,   31   ,  300   ,  20   , 'c'],
  ['1/2/2018'  ,   61   ,  100   ,   8   , 'd'],
  ['1/2/2018'  ,   61   ,  200   ,  17  ,  'e'],
  ['1/2/2018'  ,   61   ,  300   ,  30   , 'f']]


df = pd.DataFrame(data=data, columns=['Date','Duration','Item','Value','ID'])

df1 = df.groupby('Date', as_index=False)[['Duration']].max()
df2 = pd.merge(df,df1, how='inner')

#target_value = 19
df2['diff']=(df2.Value-target_value).abs()

result=df2.loc[df2.groupby('Date')['diff'].idxmin()]

结果数据框包含最接近您输入值的值。 如果您只想要“ ID”列,那么

IDresult = result[['ID']]

答案 1 :(得分:0)

您可以执行以下操作:

target_value = 15
df['max_duration'] = df.groupby('Date')['Duration'].transform('max')
df.query('max_duration == Duration')\
  .assign(dist=lambda df: np.abs(df['Value'] - target_value))\
  .assign(min_dist=lambda df: df.groupby('Date')['dist'].transform('min'))\
  .query('min_dist == dist')\
  .loc[:, ['Date', 'ID']

结果:

        Date ID
4   1/1/2018  e
11  1/2/2018  e

答案 2 :(得分:0)

遵循您的逻辑:

idx = df.groupby(['Date'])['Duration'].transform(max) == df['Duration']
#tgt_value = 19
d = df[idx]
d['dist']=(d['Value'] - 19).abs()

Row_result = d.loc[d['dist'].idxmin()]