【问题标题】:Python Pandas: Check the value of a column over multiple rows with the same indexPython Pandas:检查具有相同索引的多行的列值
【发布时间】:2020-08-20 11:39:53
【问题描述】:

我有一个非常复杂的(对我而言)情况,我需要处理一个数据帧,其中每个索引都有多行,根据特定列的值,这可能是三种情况之一。

数据框如下所示:

Index   Account Postfix ID  val1    val2
AA11    AA      11      aa  1       2
AA11    AA      11      aa  1       2
AA11    AA      11      aa  1       2
BB22    BB      22      bb  1       1
BB22    BB      22      NA  2       2
BB22    BB      22      NA  3       3
CC33    CC      33      NA  1       2
CC33    CC      33      NA  1       2
CC33    CC      33      NA  1       2

每个唯一索引都可以属于以下三种情况之一:

  • 答:总是填充 ID,从每个索引的第一行获取 val1 和 val2
  • S:有时会填充 ID,从 ID != Na 的行中获取 val1,从 ID = Na 的行中获取 val2 的总和
  • N:从不填充 ID,将所有行的 val1 和 val2 相加

我的第一个问题是我不知道如何检查同一索引的多行中的列值。

我在想这样的事情:

indices = df.index.unique()
for index in indices:
    df[ScenarioA] = np.all(df.loc[index, ID])
    df[ScenarioN] = np.all(np.logical_not(df.loc[index, ID]))
    df[ScenarioS] = np.logical_and(np.logical_not(df[ScenarioA]),np.logical_not(df[ScenarioN]))

但这会导致所有行都被标记为 ScenarioN,而实际上结果应该如下所示:

Index   Account Postfix ID  val1    val2  ScenarioA ScenarioS ScenarioN
AA11    AA      11      aa  1       2     True      False     False
AA11    AA      11      aa  1       2     True      False     False
AA11    AA      11      aa  1       2     True      False     False
BB22    BB      22      bb  1       1     False     True      False
BB22    BB      22      NA  2       2     False     True      False
BB22    BB      22      NA  3       3     False     True      False
CC33    CC      33      NA  1       2     False     False     True
CC33    CC      33      NA  1       2     False     False     True
CC33    CC      33      NA  1       2     False     False     True

完成后,我需要执行求和并得到类似下面的结果,但我认为这部分不会太难,因为我可以通过 Scenario 并根据需要执行计算:

Index   Account Postfix ID  val1    val2
AA11    AA      11      aa  1       2
BB22    BB      22      bb  1       5
CC33    CC      33      NA  3       6

我在尝试将 T/F 分配给 Scenario 列的部分做错了什么?

【问题讨论】:

    标签: python pandas numpy dataframe indexing


    【解决方案1】:

    不确定这是否是你所追求的,希望它能指导你解决你的具体挑战:

    grouping = df.groupby('Index').ID
    
    #create some anonymous functions
    #determine groups that completely have no null
    #those that have some null
    #those that have nulls all through
    alls = lambda x: x.isna().all()
    anys = lambda x: x.isna().any()
    notnull = lambda x: x.notna().all()
    all_null = grouping.apply(alls)
    any_null = grouping.apply(anys)
    all_not_null = grouping.apply(notnull)
    
    #get the individual groups
    full = all_not_null.index[all_not_null.array]
    empty = all_null.index[all_null.array]
    partially_empty = any_null.index[any_null.array].difference(empty)
    
    #get the different dataframes for each group
    step1 = df.loc[df.Index.isin(full)].groupby('Index').first()
    
    
    #some nulls
    cond1 = df.Index.isin(partially_empty) & (df.ID.notna())
    cond2 = df.Index.isin(partially_empty) &(df.ID.isna())
    
    step2 = df.loc[cond1]
    step2 = step2.assign(val2 = df.loc[cond2,'val2'].sum())
    
    #nulls all the way
    step3 = df.loc[df.Index.isin(empty)]
    temp = step3.groupby(['Index']).agg({'val1':'sum','val2':'sum'})
    
    step3 = step3.drop_duplicates('Index')
    step3 = step3.assign(val1 = temp['val1'].squeeze(), val2 = temp['val2'].squeeze())
    
    #combine the three dataframes
    pd.concat([step1.reset_index(),step2,step3],ignore_index=True)
    
        Index   Account Postfix ID  val1    val2
    0   AA11      AA      11    aa    1      2
    1   BB22      BB      22    bb    1      5
    2   CC33      CC      33    NaN   3      6
    

    【讨论】:

    • 这真的很有用。它不适合我的实际用例 100%,但是 groupby 和 lambas 将每个场景的数据框拆分为一个帮助我实现了该功能,我认为现在我为每个场景都有一个数据框,我应该能够计算出总和使用您的总和、聚合和挤压示例作为基点。感谢您的帮助
    猜你喜欢
    • 2021-02-22
    • 1970-01-01
    • 2020-08-18
    • 1970-01-01
    • 2020-08-20
    • 1970-01-01
    • 2022-01-11
    • 2022-12-17
    • 2021-04-20
    相关资源
    最近更新 更多