在列中插入条件行
Posted
技术标签:
【中文标题】在列中插入条件行【英文标题】:Insert Conditional Rows in Columns 【发布时间】:2020-04-06 02:44:18 【问题描述】:我目前有一个跟踪已完成 5 次测试的数据集,但是,它只显示已完成测试的人,而不是尚未参加测试的人 - 示例如下:
Name Test Completed
John Math-Test1 Yes
John Math-Test2 Yes
John Math-Test3 Yes
John Math-Test4 Yes
John Math-Test5 Yes
Lauren Math-Test1 Yes
Lauren Math-Test2 Yes
Lauren Math-Test3 Yes
Tom Math-Test1 Yes
Tom Math-Test2 Yes
Tom Math-Test3 Yes
Tom Math-Test4 Yes
Tom Math-Test5 Yes
如您所见,Lauren 尚未参加“Math-Test4”和“Math-Test5”测试,因此她的名字没有出现。我想添加一个选项,让“已完成”列在有人未完成测试时显示“否”。
所需的输出如下:
Name Test Completed
John Math-Test1 Yes
John Math-Test2 Yes
John Math-Test3 Yes
John Math-Test4 Yes
John Math-Test5 Yes
Lauren Math-Test1 Yes
Lauren Math-Test2 Yes
Lauren Math-Test3 Yes
*Lauren Math-Test4 No* - Add these rows automatically
*Lauren Math-Test5 No*
Tom Math-Test1 Yes
Tom Math-Test2 Yes
Tom Math-Test3 Yes
Tom Math-Test4 Yes
Tom Math-Test5 Yes
如何使用 Python/Pandas/Numpy 实现这一点?
感谢所有可以提供帮助的人!
编辑 - 更新:在尝试@Scott Boston 的代码后,我得到了这个:
idx = pd.MultiIndex.from_product([df['Name'].unique(),
df['Test'].unique()],
names=['Name','Test'])
newidx = idx[~idx.isin(df.set_index(['Name','Test']).index)]
pd.concat([df,
newidx.to_series().reset_index().assign(Completed="No*")[['Name','Test','Completed']]], ignore_index=True)
输出:
Name1 Test Completed
John Math-Test1 Yes
John Math-Test2 Yes
John Math-Test3 Yes
John Math-Test4 Yes
John Math-Test5 Yes
Lauren Math-Test1 Yes
Lauren Math-Test2 Yes
Lauren Math-Test3 Yes
Tom Math-Test1 Yes
Tom Math-Test2 Yes
Tom Math-Test3 Yes
Tom Math-Test4 Yes
Tom Math-Test5 Yes
John Math-Test3 No*
John Math-Test4 No*
John Math-Test5 No*
John Math-Test2 No*
Lauren Math-Test3 No*
Lauren Math-Test4 No*
Lauren Math-Test5 No*
Lauren Math-Test2 No*
Lauren Math-Test5 No*
Lauren Math-Test1 No*
Lauren Math-Test2 No*
Lauren Math-Test4 No*
Lauren Math-Test5 No*
现在只需要找到方法来删除不需要的行以获得所需的输出。
【问题讨论】:
【参考方案1】:试试,让我们使用多索引与from_product
、set_index
和reindex
,
此方法适用于所有“看到”的值,如果没有看到某个值,则需要在 from_product 方法中使用硬编码列表:
idx = pd.MultiIndex.from_product([df['Name'].unique(),
df['Test'].unique()],
names=['Name','Test'])
df.set_index(['Name','Test']).reindex(idx, fill_value='No*').reset_index()
输出:
Name Test Completed
0 John Math-Test1 Yes
1 John Math-Test2 Yes
2 John Math-Test3 Yes
3 John Math-Test4 Yes
4 John Math-Test5 Yes
5 Lauren Math-Test1 Yes
6 Lauren Math-Test2 Yes
7 Lauren Math-Test3 Yes
8 Lauren Math-Test4 No*
9 Lauren Math-Test5 No*
10 Tom Math-Test1 Yes
11 Tom Math-Test2 Yes
12 Tom Math-Test3 Yes
13 Tom Math-Test4 Yes
14 Tom Math-Test5 Yes
更新
idx = pd.MultiIndex.from_product([df['Name'].unique(),
df['Test'].unique()],
names=['Name','Test'])
newidx = idx[~idx.isin(df.set_index(['Name','Test']).index)]
pd.concat([df,
newidx.to_series().reset_index().assign(Completed="No*")[['Name','Test','Completed']]], sort=True, ignore_index=True)
【讨论】:
嗨,斯科特,谢谢分享!我在工作中尝试将代码添加到我的数据集,但遇到了一个异常ValueError: cannot handle a non-unique multi-index!
,我承认我的数据集中确实有其他几列数据,这可能与它有关吗?
是的,我构建了类似于建议的脚本:from_product([df['Name'].unique(), df['Test'].unique()], names=['Name','Test'])
我不应该这样做吗?抱歉,如果我没有提供足够的详细信息。
啊..是的,我想我知道这里发生了什么。
感谢您的帮助 @Scott Boston,更新后的代码出现了一个不同的异常:NameError: name 'idx' is not defined
- 我应该以某种方式定义 idx 吗?
使用本答案第一部分中定义的 idx。以上是关于在列中插入条件行的主要内容,如果未能解决你的问题,请参考以下文章