【问题标题】:Test for First Occurrence of Conditions in Python Dataframe测试 Python Dataframe 中条件的首次出现
【发布时间】:2021-04-22 03:37:51
【问题描述】:

背景

对 Python 和数据帧来说非常陌生。我在 Firefox (87.0) 中运行 Jupyter Notebook 的 Mac (Sierra) 上。我有一个这样的数据框:

df = pd.DataFrame({'A':[1,2,3,4,5,6,7,8,9,10],
                   'SubGroup':[1,5,6,5,8,6,8,6,6,5],
                   'Price':[7,1,0,10,2,3,0,0,10,0]})

    A  SubGroup  Price
0   1         1      7
1   2         5      1
2   3         6      0
3   4         5     10
4   5         8      2
5   6         6      3
6   7         8      0
7   8         6      0
8   9         6     10
9  10         5      0

我想在此数据框中添加一个布尔列,以检查 a) 该行中的价格是否为零,以及 b) 是否是该子组的零价格第一次出现(从上到下读取)。如果 (a) 和 (b) 都为真,则返回真,否则返回假。所以它应该是这样的:

    A  SubGroup  Price   Test
0   1         1      7  False   
1   2         5      1  False
2   3         6      0   True
3   4         5     10  False
4   5         8      2  False
5   6         6      3  False
6   7         8      0   True
7   8         6      0  False
8   9         6     10  False
9  10         5      0   True

我的尝试

第一个条件(价格 == 0)很简单。检查它是否是子组的第一次出现是我可以使用一些帮助的地方。我有 Excel 背景,所以我开始思考如何使用 MINIFS 函数解决这个问题。这个想法是找到子组的最低价格,只查看当前行上方的行。如果该最小值大于零,那么我会知道这是第一次出现零。我能找到的最接近的(来自this post)是类似...

df['subgroupGlobalMin'] = df.groupby('SubGroup')['Price'].transform('min')

...它有效,但在子组的所有行中采用全局最小值,而不仅仅是当前行上方的行。所以我尝试使用 iloc 为我的 min 指定目标范围,就像这样......

df['subgroupPreviousMin'] = df.iloc[:df.index].groupby('SubGroup')['Price'].transform('min')

...但这会产生错误“无法使用 RangeIndex 类型的这些索引器 [RangeIndex(start=0, stop=10, step=1)] 在 RangeIndex 上进行位置索引”。我不知道如何动态指定我的行/索引。

所以我改变了策略,而是尝试使用 idxmin(如 this post)查找子组最小值第一次出现的索引:

df['minIndex'] = df.groupby(['SubGroup'])[['Price']].idxmin()

计划是使用 df.index 对照当前行索引来检查它,但我在这里得到了意外的输出:

    A  SubGroup  Price  minIndex
0   1         1      7       NaN
1   2         5      1       0.0
2   3         6      0       NaN
3   4         5     10       NaN
4   5         8      2       NaN
5   6         6      3       9.0
6   7         8      0       2.0
7   8         6      0       NaN
8   9         6     10       6.0
9  10         5      0       NaN

我知道它在这里做什么,但我不知道为什么或如何解决它。

问题

  1. 哪种策略最适合我想要实现的目标 - 使用 min 函数、使用 idxmin 之类的东西检查索引或其他东西?
  2. 我应该如何在我的数据框中添加一列来检查该行的价格是否为 0,以及该子组是否第一次出现零?

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    让我们试试你的逻辑:

    is_zero = df.Price.eq(0)
    is_first_zero = is_zero.groupby(df['SubGroup']).cumsum().eq(1)
    
    df['Test'] = is_zero & is_first_zero
    

    输出:

        A  SubGroup  Price   Test
    0   1         1      7  False
    1   2         5      1  False
    2   3         6      0   True
    3   4         5     10  False
    4   5         8      2  False
    5   6         6      3  False
    6   7         8      0   True
    7   8         6      0  False
    8   9         6     10  False
    9  10         5      0   True
    

    【讨论】:

      猜你喜欢
      • 2013-02-03
      • 1970-01-01
      • 2015-11-17
      • 2012-04-21
      • 2022-08-17
      • 1970-01-01
      • 2017-01-08
      • 1970-01-01
      • 2021-03-02
      相关资源
      最近更新 更多