【问题标题】:Iterate over rows and select all between max and min遍历行并选择最大值和最小值之间的所有内容
【发布时间】:2021-05-07 15:09:00
【问题描述】:

假设我有一个如下所示的 Pandas DataFrame:

ID  update_time     cap date      diff
A   05/05/21 1:45   136 05/05/21    136
A   05/05/21 1:50   0   05/05/21    -136
A   05/05/21 2:10   1   05/05/21    1
A   05/05/21 2:15   0   05/05/21    -1
A   05/05/21 3:35   1   05/05/21    1
A   05/05/21 3:40   0   05/05/21    -1
A   05/05/21 14:40  158 06/05/21    158
A   05/05/21 14:45  0   06/05/21    -158
A   05/05/21 15:10  1   06/05/21    1
A   07/05/21 9:49   0   07/05/21    -1
B   05/05/21 1:10   500 05/05/21    500
B   05/05/21 1:15   63  05/05/21    -437
B   05/05/21 1:20   0   05/05/21    -63
B   05/05/21 1:35   8   05/05/21    8
B   05/05/21 1:40   0   05/05/21    -8
B   05/05/21 1:45   3   05/05/21    3
B   05/05/21 1:50   0   05/05/21    -3
B   05/05/21 14:35  255 06/05/21    255
B   05/05/21 14:40  0   06/05/21    -255

我想在每个 ID 和日期中将第一次删除后出现的任何 cap 值删除为 0。关于如何实现这一目标的任何指示?我在下面附上了预期的输出。

ID  update_time     cap date      diff
A   05/05/21 1:45   136 05/05/21    136
A   05/05/21 1:50   0   05/05/21    -136
A   05/05/21 14:40  158 06/05/21    158
A   05/05/21 14:45  0   06/05/21    -158
B   05/05/21 1:10   500 05/05/21    500
B   05/05/21 1:15   63  05/05/21    -437
B   05/05/21 1:20   0   05/05/21    -63
B   05/05/21 14:35  255 06/05/21    255
B   05/05/21 14:40  0   06/05/21    -255

任何指针将不胜感激!

【问题讨论】:

  • “在它们最初下降到 0 之后”是什么意思?如果我们排除 0 之后的所有内容,为什么“A,158”存在行,为什么不考虑“A,1”行?
  • A, 158 被选中,因为“日期”列中的值发生了变化。
  • @thinrhino 这是一个重要的细节,我建议您将其添加到您的问题中!

标签: python pandas dataframe data-science


【解决方案1】:

您需要首先对IDdate 执行groupby,因为您需要"all rows before a drop to 0 occurs in caps" 用于每个唯一的ID-日期组合。然后我们将应用一个自定义函数来选择第一个零出现之前的所有行。该函数考虑了对于仅出现一次的 ID 日期不会发生“下降到 0”的边缘情况。

请注意,我只使用了您的 DataFrame 的相关部分。

import numpy as np
import pandas as pd

## recreate the relevant portion of your DataFrame
df = pd.DataFrame({
    'ID':['A']*10+['B']*9,
    'cap':[136,0,1,0,1,0,158,0,1,0,500,63,0,8,0,3,0,255,0],
    'date':['05/05/21']*6+['06/05/21']*3+['07/05/21']+['05/05/21']*7+['06/05/21']*2
})

## get the caps values before the first occurrence of a zero 
def get_caps_before_zero(df_column):
    ## for an ID-cap groupby of length 1, no "drop" to zero can occur, so return an empty DataFrame
    if len(df_column) == 1:
        return df_column.iloc[0:0]
    else:
        idx_first_zero = np.where(df_column == 0)[0].min() + 1
        return df_column.iloc[:idx_first_zero]

df_subset = (df.groupby(['ID','date'])
    .apply(lambda x: get_caps_before_zero(x['cap']))
    .reset_index()
    .drop(columns='level_2')
)

输出:

>>> df_subset
  ID      date  cap
0  A  05/05/21  136
1  A  05/05/21    0
2  A  06/05/21  158
3  A  06/05/21    0
4  B  05/05/21  500
5  B  05/05/21   63
6  B  05/05/21    0
7  B  06/05/21  255
8  B  06/05/21    0

【讨论】:

  • 感谢您的解决方案。了解了一些关于熊猫的新知识。
  • 没问题,很高兴我的解决方案有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-14
  • 2012-10-09
  • 2015-09-12
  • 2021-09-10
  • 1970-01-01
  • 2020-08-19
  • 1970-01-01
相关资源
最近更新 更多