Python 在数据帧上迭代的Pandaic方法
我正在用excel输入制作测试团队报告;使用熊猫收集、过滤、处理数据 我编写了下面的代码来制作产品测试用例封面表,以便以后使用/轻松搜索。第三列为测试用例类型。我在一个excel中有多个测试用例,所以我需要遍历所有单元格并拆分测试,以形成产品测试用例对 因为我对熊猫不太熟悉,而且我在其他地方也没有找到更好的方法,所以我想问一下,是否有更多的蟒蛇式方法或者更简单的熊猫式方法可以做到同样的效果和效率 带有示例数据的代码(\n是excel单元格中的换行符): 制作:Python 在数据帧上迭代的Pandaic方法,python,pandas,dataframe,iteration,Python,Pandas,Dataframe,Iteration,我正在用excel输入制作测试团队报告;使用熊猫收集、过滤、处理数据 我编写了下面的代码来制作产品测试用例封面表,以便以后使用/轻松搜索。第三列为测试用例类型。我在一个excel中有多个测试用例,所以我需要遍历所有单元格并拆分测试,以形成产品测试用例对 因为我对熊猫不太熟悉,而且我在其他地方也没有找到更好的方法,所以我想问一下,是否有更多的蟒蛇式方法或者更简单的熊猫式方法可以做到同样的效果和效率 带有示例数据的代码(\n是excel单元格中的换行符): 制作: prod testcase
prod testcase category
0 TS001 001_002 activate
1 TS001 001_004 activate
2 TS001 004_005 deactivate
3 TS001 006_008 deactivate
4 TS002 003_008 activate
5 TS002 024_080 activate
6 TS002 001_008 deactivate
谢谢你的建议。这里有一种方法,可能有更好的方法。在这里,支票应该是最有效的
In [2807]: (df.set_index('prod')
.applymap(lambda x: x.split('\n'))
.stack()
.apply(pd.Series)
.stack()
.reset_index(name='testcase')
.rename(columns={'level_1': 'category'})
.drop('level_2', 1))
Out[2807]:
prod category testcase
0 TS001 activate 001_002
1 TS001 activate 001_004
2 TS001 deactivate 004_005
3 TS001 deactivate 006_008
4 TS002 activate 003_008
5 TS002 activate 024_080
6 TS002 deactivate 001_008
细节
In [2809]: df
Out[2809]:
activate deactivate prod
0 001_002\n001_004 004_005\n006_008 TS001
1 003_008\n024_080 001_008 TS002
使用:
- 喜欢你的解决方案吗
- 用于使用lambda函数处理多个列,用于
by和DataFrame
和重塑byexpand=True
- 对于要
多索引的列
- 首先用于删除级别,然后用于多索引列
- 重命名列
- 用于列的更改顺序
理解地
pd.DataFrame(
[(p, t, c) for (p, c), r in df.stack().items() for t in r.split()],
columns=['prod', 'testcase', 'category']
)
prod testcase category
0 TS001 001_002 activate
1 TS001 001_004 activate
2 TS001 004_005 deactivate
3 TS001 006_008 deactivate
4 TS002 003_008 activate
5 TS002 024_080 activate
6 TS002 001_008 deactivate
解释
df.stack()
prod
TS001 activate 001_002\n001_004
deactivate 004_005\n006_008
TS002 activate 003_008\n024_080
deactivate 001_008
dtype: object
当迭代df.stack().items()
时,我们得到的元组的索引值是第一个元素,值是第二个元素。因为我们进行了堆叠,索引值本身就是一个元组。第一对看起来像:
(('TS001', 'activate'), '001_002\n001_004')
通过对'001\u 002\n001\u 004'.split()
的后续迭代,并重新排列未打包的元素,我们得到
[(p, t, c) for (p, c), r in df.stack().items() for t in r.split()]
[('TS001', '001_002', 'activate'),
('TS001', '001_004', 'activate'),
('TS001', '004_005', 'deactivate'),
('TS001', '006_008', 'deactivate'),
('TS002', '003_008', 'activate'),
('TS002', '024_080', 'activate'),
('TS002', '001_008', 'deactivate')]
然后我将其包装在一个pd.DataFrame
构造函数中,在其中我命名列。使用df.applymap
、df.melt
和df.stack
恐怕,如果另一行的
prod
等于TS001
或TS002
,这将不起作用。不确定,不要测试它。我得走了,等会儿再说。谢谢你的回答!它确实有效。我无法让apply/applymap自己工作,因此我以for循环结束。我有一个改进,请给我一点时间。是的,需要取消堆栈而不是堆栈,然后总体工作正常。谢谢您的快速回答!我在研究apply/applymap,但没能完成。我注意到了这一点,你最近对复杂理解的迷恋;)一个简洁的回答!我倾向于一次滥用一个维度。我经历了一个query
阶段,一个pd.factorize
阶段,一个stack
阶段。甚至是一个pokemon
阶段。。。。等等,那没关系!先生,如果可以,请添加基准。我认为,这在很大程度上比其他方法更有效,这个答案值得关注。这看起来确实很好。谢谢你的解释。对其他人的一个澄清是,这个答案在后面:df=df.set_index('prod')这是如此整洁和干净。谢谢你的回答@PetrSzturc对所有新用户的法定说明:您可以。
(('TS001', 'activate'), '001_002\n001_004')
[(p, t, c) for (p, c), r in df.stack().items() for t in r.split()]
[('TS001', '001_002', 'activate'),
('TS001', '001_004', 'activate'),
('TS001', '004_005', 'deactivate'),
('TS001', '006_008', 'deactivate'),
('TS002', '003_008', 'activate'),
('TS002', '024_080', 'activate'),
('TS002', '001_008', 'deactivate')]
df = df.applymap(str.split).reset_index().melt('prod', \
['activate', 'deactivate']).set_index(['prod', 'variable'])
df = pd.DataFrame(df.value.tolist(), index=df.index)\
.stack().reset_index().drop('level_2', 1)
df.columns = ['prod', 'category', 'testcase']
df
prod category testcase
0 TS001 activate 001_002
1 TS001 activate 001_004
2 TS002 activate 003_008
3 TS002 activate 024_080
4 TS001 deactivate 004_005
5 TS001 deactivate 006_008
6 TS002 deactivate 001_008