Разбить список в строке на несколько строк - PullRequest
1 голос
/ 15 октября 2019

У меня есть фрейм данных pandas, где некоторые строки содержат список результатов, которые возвращаются из системы. Я пытаюсь разбить эти списки на более мелкие порции (в воспроизводимом примере ниже, порции по 2) с каждым порцией в виде новой строки. Я понял, что могу использовать функцию numpy repeat, чтобы дублировать строки, чтобы иметь строку для каждого фрагмента, который мне нужен, но тогда я не уверен, как включить в результат только фрагмент списка в Result. (т.е. строка должна быть ['SUCCESS', 'Misc], а следующая ['Doom'] против строки [['SUCCESS', 'Misc'],['Doom']])

Я знаю, что лучшим решением было бы просто сделать каждый элемент в списке новой строкой, используя explode но из-за требований клиента это не вариант.

Код

import pandas as pd
import numpy as np

data = {'Result': [['SUCCESS'], ['SUCCESS'], ['FAILURE'], ['Pending', 'Pending', 'SUCCESS', 'Misc', 'Doom'], ['FAILURE'], ['Pending', 'SUCCESS']], 'Date': ['10/10/2019', '10/09/2019', '10/08/2019', '10/07/2019', '10/06/2019', '10/05/2019']}
goal = {'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', '10/04/2019']}

df = pd.DataFrame(data)

df['len_res'] = df['Result'].str.len()

def chunking(l, n):
    for i in range(0, len(l), n):
        yield l[i:i + n]


df['chunks'] = 1
for i in range(len(df)):
    if df['len_res'][i] > 2:
        df['Result'][i] = list(chunking(df['Result'][i], 2))
        df['chunks'][i] = len(df['Result'][i])
    else:
        pass

Фактический выход

                                          Result        Date  len_res  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, Misc], [Doom]]  10/07/2019        5       3
4                                      [FAILURE]  10/06/2019        1       1
5                             [Pending, SUCCESS]  10/05/2019        2       1

Требуемый выход

                                          Result        Date  len_res  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]  10/07/2019        5       3
4                                [SUCCESS, Misc]  10/07/2019        5       3
5                                         [Doom]  10/07/2019        5       3
6                                      [FAILURE]  10/06/2019        1       1
7                             [Pending, SUCCESS]  10/05/2019        2       1

С np.repeat

df = df.loc[np.repeat(df.index.values, df.chunks)]
df = df.reset_index(drop=True)

                                          Result        Date  len_res  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, Misc], [Doom]]  10/07/2019        5       3
4  [[Pending, Pending], [SUCCESS, Misc], [Doom]]  10/07/2019        5       3
5  [[Pending, Pending], [SUCCESS, Misc], [Doom]]  10/07/2019        5       3
6                                      [FAILURE]  10/06/2019        1       1
7                             [Pending, SUCCESS]  10/05/2019        2       1

1 Ответ

1 голос
/ 16 октября 2019

Если вы работаете в pandas v0.25 или новее, используйте explode:

size = 2
df['Result'] = df['Result'].apply(lambda r: np.array_split(r, np.ceil(len(r) / size)))
df['chunks'] = df['Result'].str.len()

df = df.explode('Result')

np.array_split разбивает массив на n = ceil(len(r) / size) частей:

[1]     --> [[1]]
[1,2]   --> [[1,2]]
[1,2,3] --> [[1,2], [3]]

explode повторяет каждую строку для каждого элемента на самом внешнем уровне массива в Result.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...