我有一个相当复杂(对我来说)的情况,我需要处理一个数据框架,该数据框架中的每个索引都有多条记录,这些记录可以是三种情况之一,取决于某列的值。
数据框架是这样的。
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
每个唯一的索引可以分为三种情况之一:
我的第一个问题是,我想不出如何跨多行检查同一索引的列的值。
我当时想的是这样的。
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
一旦我完成了这些,我就需要进行求和,并最终得到下面这样的结果,但我认为这部分不会太难,因为我可以根据场景进行计算。
Index Account Postfix ID val1 val2
AA11 AA 11 aa 1 2
BB22 BB 22 bb 1 5
CC33 CC 33 NA 3 6
在我尝试将TF分配到场景列的部分,我做错了什么?
不知道这是否是你所追求的,希望它能指导你解决你的具体挑战。
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