使用idxmax和idxmin更改不同行中的值

2024-10-01 13:36:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试找到最干净、最泛化的方法来创建一个新列,该列具有同一行中一列的最小值和另一列中的最大值。其余的值可以是nan,因为我将进行插值

rng = pd.date_range(start=datetime.date(2020,8,1), end=datetime.date(2020,8,3), freq='H')
df = pd.DataFrame(rng, columns=['date'])
df.index=pd.to_datetime(df['date'])
df.drop(['date'],axis=1,inplace=True)
df['val0']=np.random.randint(0,50,49)
df['val1']=np.random.randint(0,50,49)

df(复制剪切粘贴)的一种实现:

                     val0  val1
date                           
2020-08-01 00:00:00    17     4
2020-08-01 01:00:00    89     0
2020-08-01 02:00:00    85    48
2020-08-01 03:00:00    83    13
2020-08-01 04:00:00    56    65
2020-08-01 05:00:00    48    31
2020-08-01 06:00:00    55    11
2020-08-01 07:00:00    15    87
2020-08-01 08:00:00    92    70
2020-08-01 09:00:00    95    57
2020-08-01 10:00:00    68    79
2020-08-01 11:00:00    87     7
2020-08-01 12:00:00    43    15
2020-08-01 13:00:00    23     4
2020-08-01 14:00:00    68    13
2020-08-01 15:00:00    68    63
2020-08-01 16:00:00    28    86
2020-08-01 17:00:00    12    40
2020-08-01 18:00:00    51    20
2020-08-01 19:00:00    20    48
2020-08-01 20:00:00    79    78
2020-08-01 21:00:00    67    89
2020-08-01 22:00:00    46    52
2020-08-01 23:00:00     7    47
2020-08-02 00:00:00    14    73
2020-08-02 01:00:00    70    30
2020-08-02 02:00:00     2    39
2020-08-02 03:00:00    65    81
2020-08-02 04:00:00    65     8
2020-08-02 05:00:00    83    60
2020-08-02 06:00:00     1    64
2020-08-02 07:00:00    13    63
2020-08-02 08:00:00    45    78
2020-08-02 09:00:00    83     7
2020-08-02 10:00:00    75     0
2020-08-02 11:00:00    52     3
2020-08-02 12:00:00    59    34
2020-08-02 13:00:00    54    57
2020-08-02 14:00:00    90    66
2020-08-02 15:00:00    82    56
2020-08-02 16:00:00     9     2
2020-08-02 17:00:00     5    51
2020-08-02 18:00:00    67    96
2020-08-02 19:00:00    18    77
2020-08-02 20:00:00    28    89
2020-08-02 21:00:00    96    53
2020-08-02 22:00:00    28    46
2020-08-02 23:00:00    41    87
2020-08-03 00:00:00    26    47

现在,我找到了的idxmax和idxmin:

minidx=df.groupby(pd.Grouper(freq='D')).idxmin()
maxidx=df.groupby(pd.Grouper(freq='D')).idxmax()

minidx:

                          val0                val1
date                                              
2020-08-01 2020-08-01 23:00:00 2020-08-01 01:00:00
2020-08-02 2020-08-02 06:00:00 2020-08-02 10:00:00
2020-08-03 2020-08-03 00:00:00 2020-08-03 00:00:00

maxidx:

                          val0                val1
date                                              
2020-08-01 2020-08-01 09:00:00 2020-08-01 21:00:00
2020-08-02 2020-08-02 21:00:00 2020-08-02 18:00:00
2020-08-03 2020-08-03 00:00:00 2020-08-03 00:00:00

在这种情况下,我希望将位于2020-08-01 23:00:00的最小日值(7)放入2020-08-01 21:00:00的新列中(即与89相邻,日最大值1),并对所有其他日期执行相同操作,以便2020-08-02 18:00:00的“新”值将为1(即2020-08-02 06:00:00发生的最小日值)

我尝试了以下方法,但我只得到了一堆NaN:

df.loc[maxidx['val1'].values,'new']=df.loc[minidx['val0'].values,'val0']

如果我只是将它设置为int(df.loc[maxidx['val1'].values,'new']=6),我会在需要新值的地方得到int。我想要的值是由df.loc[minidx['val0'].values,'val0']给出的,但我似乎无法将它们放入数据帧中

minidx['val0'].valuesmaxidx['val1'].values是大小相同的数组,元素类型为numpy.datetime64,它们都是从相同的数据帧生成的,因此maxidx和minidx应该存在于df.index(df.index.values)中

有没有一个明显的原因,这是不工作的?谢谢


Tags: 方法dfdatetimedateindexnplocpd
2条回答

我发现的最简单的解决方案是通过idxmin和idxmax循环:

for v0,v1 in zip(minidx['val0'].values,maxidx['val1'].values):
    df.loc[v1,'new']=df.loc[v0,'val0']

这给了我我想要的,但似乎不是很泛泛,所以任何其他的建议,以实现同样的事情将是伟大的

IIUC,您可以使用NamedAgg执行此操作:

df.groupby(pd.Grouper(freq='D')).agg(val0_min_time=('val0','idxmin'),
                                     val0_min_value=('val0','min'),
                                     val0_max_time=('val0','idxmax'),
                                     val0_max_value=('val0','max'),
                                     val1_min_time=('val1','idxmin'),
                                     val1_min_value=('val1','min'),
                                     val1_max_time=('val1','idxmax'),
                                     val1_max_value=('val1','max'),)

输出:

                 val0_min_time  val0_min_value       val0_max_time  val0_max_value       val1_min_time  val1_min_value       val1_max_time  val1_max_value
date                                                                                                                                                      
2020-08-01 2020-08-01 23:00:00               7 2020-08-01 09:00:00              95 2020-08-01 01:00:00               0 2020-08-01 21:00:00              89
2020-08-02 2020-08-02 06:00:00               1 2020-08-02 21:00:00              96 2020-08-02 10:00:00               0 2020-08-02 18:00:00              96
2020-08-03 2020-08-03 00:00:00              26 2020-08-03 00:00:00              26 2020-08-03 00:00:00              47 2020-08-03 00:00:00              47

相关问题 更多 >