如何根据另一个列值过滤数据框中的行?
我有一个数据框,
ip_df:
class name marks min_marks min_subjects
0 I tom [89,85,80,74] 80 2
1 II sam [65,72,43,40] 85 1
基于“ min_subject”和“ min_marks”的列值,应过滤该行。
对于索引0,“ min_subjects”为“ 2”,“ marks”列中的至少2个元素应大于80,即“ min_marks”列,然后必须添加一个名为“ flag”的新列添加为1
对于索引1,“ min_subjects”为“ 1”,“ marks”列中的至少1个元素应大于85,即“ min_marks”列,然后必须新建一个名为“ flag”的列添加为0(即flag = 0,因为此处不满足条件)
最终结果应该是
op_df:
class name marks min_marks min_subjects flag
0 I tom [89,85,80,74] 80 2 1
1 II sam [65,72,43,40] 85 1 0
有人可以帮助我在数据框架中实现同样的目标吗?
答案 0 :(得分:3)
将列表理解与zip
乘以3列,比较生成器中的每个值和sum
的计数,最后用最小标记进行比较并转换为整数:
df['flag'] = [1 if sum(x > c for x in a) >= b else 0
for a, b, c in zip(df['marks'], df['min_subjects'], df['min_marks'])]
将int
转换为0,1
的布尔值的替代方法:
df['flag'] = [int(sum(x > c for x in a) >= b)
for a, b, c in zip(df['marks'], df['min_subjects'], df['min_marks'])]
或使用numpy
解决方案:
df['flag'] = [int(np.sum(np.array(a) > c) >= b)
for a, b, c in zip(df['marks'], df['min_subjects'], df['min_marks'])]
print (df)
class name marks min_marks min_subjects flag
0 I tom [89, 85, 80, 74] 80 2 1
1 II sam [65, 72, 43, 40] 85 1 0
答案 1 :(得分:1)
要避免for
循环并充分利用并行计算,可以使用新函数explode
(Pandas 0.25.0):
df1 = df.explode('marks')
print(df1)
输出:
class name marks min_marks min_subjects
0 I tom 89 80 2
0 I tom 85 80 2
0 I tom 80 80 2
0 I tom 74 80 2
1 II sam 65 85 1
1 II sam 72 85 1
1 II sam 43 85 1
1 II sam 40 85 1
比较列marks
和min_marks
:
df['flag'] = df1['marks'].gt(df1['min_marks'])\
.groupby(df1.index).sum().ge(df['min_subjects']).astype(int)
print(df)
输出:
class name marks min_marks min_subjects flag
0 I tom [89, 85, 80, 74] 80 2 1
1 II sam [65, 72, 43, 40] 85 1 0