有条件地拆分冗长行的最 Pythonic/有效方法是什么?



我有一个带有列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}}

我建议将每个pending/SUCCESS/FAILURE放在一行上,如果您使用的是熊猫 0.25+,请使用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

你可以做

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]

最新更新