我有一个数据列,其中列Results
可能会很长。由于数据框最终出现在Excel报表中,因此这是有问题的,因为Excel仅在不显示所有数据之前才会排成一行。相反,我想做的是将具有一定长度的结果的行拆分为多行。
我在小规模的数据框架上编写了一些代码,将结果分成2个大块。我还没有弄清楚如何将每个大块放入新行中。另外,当我的数据帧从6行增加到35k +时,我不确定这将是最有效的方法。什么是实现我想要的最有效/ Pythonic方法?
原始数据框
Result Date
0 [SUCCESS] 10/10/2019
1 [SUCCESS] 10/09/2019
2 [FAILURE] 10/08/2019
3 [Pending, Pending, SUCCESS] 10/07/2019
4 [FAILURE] 10/06/2019
5 [Pending, SUCCESS] 10/05/2019
目标输出
Result Date
0 [SUCCESS] 10/10/2019
1 [SUCCESS] 10/09/2019
2 [FAILURE] 10/08/2019
3 [Pending, Pending] 10/07/2019
4 [SUCCESS] 10/07/2019
5 [FAILURE] 10/06/2019
6 [Pending, SUCCESS] 10/05/2019
代码
import pandas as pd
import numpy as np
data = {'Result': [['SUCCESS'], ['SUCCESS'], ['FAILURE'], ['Pending', 'Pending', 'SUCCESS'], ['FAILURE'], ['Pending', 'SUCCESS']], 'Date': ['10/10/2019', '10/09/2019', '10/08/2019', '10/07/2019', '10/06/2019', '10/05/2019']}
df = pd.DataFrame(data)
df['Length of Results'] = df['Result'].str.len()
def chunks(l, n):
for i in range(0, len(l), n):
yield l[i:i + n]
for i in range(len(df)):
if df['Length of Results'][i] > 2:
df['Result'][i] = list(chunks(df['Result'][i], 2))
else:
pass
df['Chunks'] = 1
for i in range(len(df)):
if df['Length of Results'][i] > 2:
df['Chunks'][i] = len(df['Result'][i])
else:
pass
df = df.loc[np.repeat(df.index.values, df.Chunks)]
df = df.reset_index(drop=True)
当前产生的代码
Result Date Length of Results Chunks
0 [SUCCESS] 10/10/2019 1 1
1 [SUCCESS] 10/09/2019 1 1
2 [FAILURE] 10/08/2019 1 1
3 [[Pending, Pending], [SUCCESS]] 10/07/2019 3 2
4 [[Pending, Pending], [SUCCESS]] 10/07/2019 3 2
5 [FAILURE] 10/06/2019 1 1
6 [Pending, SUCCESS] 10/05/2019 2 1
df.to_dict()
{'Result': {0: ['SUCCESS'], 1: ['SUCCESS'], 2: ['FAILURE'], 3: [['Pending', 'Pending'], ['SUCCESS']], 4: [['Pending', 'Pending'], ['SUCCESS']], 5: ['FAILURE'], 6: ['Pending', 'SUCCESS']}, 'Date': {0: '10/10/2019', 1: '10/09/2019', 2: '10/08/2019', 3: '10/07/2019', 4: '10/07/2019', 5: '10/06/2019', 6: '10/05/2019'}, 'Length of Results': {0: 1, 1: 1, 2: 1, 3: 3, 4: 3, 5: 1, 6: 2}, 'Chunks': {0: 1, 1: 1, 2: 1, 3: 2, 4: 2, 5: 1, 6: 1}}
答案 0 :(得分:1)
您可以
s=df[['Date','Result']].explode('Result')
t=s.groupby(['Date','Result'])['Result'].transform('size')>1
s.groupby([s.Date,t]).Result.agg(list).reset_index(level=0).reset_index(drop=True)
Out[65]:
Date Result
0 10/05/2019 [Pending, SUCCESS]
1 10/06/2019 [FAILURE]
2 10/07/2019 [SUCCESS]
3 10/07/2019 [Pending, Pending]
4 10/08/2019 [FAILURE]
5 10/09/2019 [SUCCESS]
6 10/10/2019 [SUCCESS]
答案 1 :(得分:1)
如果熊猫0.25+以上,我建议使用pending/SUCCESS/FAILURE
将每个df.explode
放在一行中。
df = df.explode('Result')
df.groupby(['Date','Result']).count().reset_index(name='Length')
输出:
Date Result Length
0 10/05/2019 Pending 1
1 10/05/2019 SUCCESS 1
2 10/06/2019 FAILURE 1
3 10/07/2019 Pending 2
4 10/07/2019 SUCCESS 1
5 10/08/2019 FAILURE 1
6 10/09/2019 SUCCESS 1
7 10/10/2019 SUCCESS 1