Pandas:在组复杂问题中使用条件迭代和插入列
Posted
技术标签:
【中文标题】Pandas:在组复杂问题中使用条件迭代和插入列【英文标题】:Pandas: Iterate and insert column with conditions within groups complex question 【发布时间】:2020-10-23 18:54:22 【问题描述】:我有一个非常复杂的问题,即如何为每个组添加一个包含条件的新列。这是示例数据框,
df = pd.DataFrame(
'id': ['AA', 'AA', 'AA', 'AA', 'BB', 'BB', 'BB', 'BB', 'BB',
'CC', 'CC', 'CC', 'CC', 'CC', 'CC', 'CC'],
'From_num': [80, 68, 751, 'Issued', 32, 68, 126, 'Issued', 'Missed', 105, 68, 114, 76, 68, 99, 'Missed'],
'To_num':[99, 80, 68, 751, 105, 32, 68, 126, 49, 324, 105, 68, 114, 76, 68, 99],
)
id From_num To_num
0 AA 80 99
1 AA 68 80
2 AA 751 68
3 AA Issued 751
4 BB 32 105
5 BB 68 32
6 BB 126 68
7 BB Issued 126
8 BB Missed 49
9 CC 105 324
10 CC 68 105
11 CC 114 68
12 CC 76 114
13 CC 68 76
14 CC 99 68
15 CC Missed 99
我有一个 'flag' 编号 68。在每个组中,对于 'From_num' 列中等于或高于此标志号的任何行将在新列中标记为“Forward”,任何行等于或低于标志号“To_num”列将在同一列中标记为“Back”。然而,最困难的情况是:如果这个标志号在每一列中出现多次,'From_num' 和 'To_num' 之间的行将在新列中标记为“Forward&Back”,请参见下面的 df 和预期结果。
Expected result
id From_num To_num Direction
0 AA 80 99 Forward
1 AA 68 80 Forward
2 AA 751 68 Back
3 AA Issued 751 Back
4 BB 32 105 Forward
5 BB 68 32 Forward
6 BB 126 68 Back
7 BB Issued 126 Back
8 BB Missed 49 Back
9 CC 105 324 Forward
10 CC 68 105 Forward
11 CC 114 68 Forward&Back # From line 11 to 13, flag # 68 appears more than once
12 CC 76 114 Forward&Back # so the line 11, 12 and 13 labelled "Forward&Back"
13 CC 68 76 Forward&Back
14 CC 99 68 Back
15 CC Missed 99 Back
我尝试编写了许多循环,但它们都失败了,无法获得预期的结果。因此,如果有人有想法,请提供帮助。希望问题很清楚。非常感谢!
【问题讨论】:
【参考方案1】:我已经完成了没有“真正的循环”。
-
保留行号 (
reset_index()
)
构造一个新的数据框,它是包含标志 (68) 的记录
“前进”和“后退”的简单逻辑基于第一次看到 68 之前或之后的行
“向前和向后”发生在有多次目击以及在第 2 次和第 (n-1) 次目击之间
def direction(r):
flagrow = df2[(df2["id"]==r["id"]) ]["index"].values
if r["index"] <= flagrow[0]: val = "Forward"
elif r["index"] > flagrow[0]: val = "Back"
if len(flagrow)>2 and r["index"] >= flagrow[1] and r["index"]<flagrow[-1]: val = "Forward&Back"
return val
df = pd.DataFrame(
'id': ['AA', 'AA', 'AA', 'AA', 'BB', 'BB', 'BB', 'BB', 'BB',
'CC', 'CC', 'CC', 'CC', 'CC', 'CC', 'CC'],
'From_num': [80, 68, 751, 'Issued', 32, 68, 126, 'Issued', 'Missed', 105, 68, 114, 76, 68, 99, 'Missed'],
'To_num':[99, 80, 68, 751, 105, 32, 68, 126, 49, 324, 105, 68, 114, 76, 68, 99],
)
df = df.reset_index()
df2 = df[(df.From_num==68) | (df.To_num==68)].copy()
df["Direction"] = df.apply(lambda r: direction(r), axis=1)
df
【讨论】:
非常感谢@Rob Raymond,我尝试了您的回答,效果很好。一百万谢谢!让我再试几次,然后回复你。 不客气 - 数据的关键是将其视为集合并进行基于集合的处理。过程编程概念用于控制逻辑。 Codd 早在 1970 年就做到了 :-)以上是关于Pandas:在组复杂问题中使用条件迭代和插入列的主要内容,如果未能解决你的问题,请参考以下文章