Divida uma coluna contendo uma lista em várias linhas no Pandas com base em uma condição

Souvik Ray

Eu tenho um dado parecido com o abaixo

[(datetime.datetime(2021, 2, 6, 8, 18, 1, 212763),u'[["London", "New York", "BUSY"]]'), 
(datetime.datetime(2021, 2, 6, 8, 17, 1, 18633), u'[["Mumbai", "Tokyo", "IDLE"]]'), (datetime.datetime(2021, 2, 6, 8, 16, 1, 182888), u'[["Amsterdam", "Chicago", "IDLE"], ["Amsterdam", "London", "IDLE"], ["Amsterdam", "Berlin", "BUSY"]]'), (datetime.datetime(2021, 2, 6, 8, 15, 1, 245619), u'[["Tokyo", "Moscow", "IDLE"]]'), (datetime.datetime(2021, 2, 6, 7, 18, 1, 413066), u'[["Mumbai", "Los Angeles", "IDLE"], ["Mumbai", "Berlin", "IDLE"]]'), 
(datetime.datetime(2021, 2, 6, 7, 17, 1, 154138), u'[]'), 
(datetime.datetime(2021, 2, 6, 7, 16, 1, 253111), u'[]')]

Possui duas colunas, primeiro a datee segundo a string list of list.

É assim que fica ao carregá-lo no pandas

                        date                                             status
0 2021-02-06 08:18:01.212763                   [["London", "New York", "BUSY"]]
1 2021-02-06 08:17:01.018633                      [["Mumbai", "Tokyo", "IDLE"]]
2 2021-02-06 08:16:01.182888  [["Amsterdam", "Chicago", "IDLE"], ["Amsterdam...
3 2021-02-06 08:15:01.245619                      [["Tokyo", "Moscow", "IDLE"]]
4 2021-02-06 07:18:01.413066  [["Mumbai", "Los Angeles", "IDLE"], ["Mumabi",...
5 2021-02-06 07:17:01.154138                                                 []
6 2021-02-06 07:16:01.253111                                                 []

Existem dois problemas.

Primeiro eu preciso converter o string list of listem um regular liste isso é feito fazendo algo assim

df[column].apply(literal_eval)

O segundo problema é que alguns valores de coluna contêm vários itens no liste preciso dividir cada um deles e fazer uma nova linha contendo esse valor como um independente list. Além disso, cada valor de coluna deve ser convertido em um em listvez de em list of list.

Por exemplo, tenho este valor de coluna particular

(datetime.datetime(2021, 2, 6, 8, 16, 1, 182888), u'[["Amsterdam", "Chicago", "IDLE"], ["Amsterdam", "Londom", "IDLE"], ["Amsterdam", "Berlin", "BUSY"]]')

Aqui, cada item no listdeve formar uma nova linha contendo aquele valor na coluna como a list. Algo como abaixo

2021-02-06 08:16:01.182888 ["Amsterdam", "Chicago", "IDLE"]
2021-02-06 08:16:01.182888 ["Amsterdam", "Londom", "IDLE"]
2021-02-06 08:16:01.182888 ["Amsterdam", "Berlin", "BUSY"]

Quaisquer outras colunas que tenham apenas um único item listsemelhante

(datetime.datetime(2021, 2, 6, 8, 18, 1, 212763),u'[["London", "New York", "BUSY"]]')

Isso deve ser convertido para

2021-02-06 08:18:01.212763 ["London", "New York", "BUSY"]

Portanto, o Dataframe final deve ser semelhante a

                        date                                             status
0 2021-02-06 08:18:01.212763                   ["London", "New York", "BUSY"]
1 2021-02-06 08:17:01.018633                   ["Mumbai", "Tokyo", "IDLE"]
2 2021-02-06 08:16:01.182888                   ["Amsterdam", "Chicago", "IDLE"]
3 2021-02-06 08:16:01.182888                   ["Amsterdam", "London", "IDLE"]
4 2021-02-06 08:16:01.182888                   ["Amsterdam", "Berlin", "BUSY"]
5 2021-02-06 08:15:01.245619                   ["Tokyo", "Moscow", "IDLE"]
6 2021-02-06 07:18:01.413066                   ["Mumbai", "Los Angeles", "IDLE"]
7 2021-02-06 07:18:01.413066                   ["Mumbai", "Berlin", "IDLE"]
8 2021-02-06 07:17:01.154138                                                 []
9 2021-02-06 07:16:01.253111                                                 []

Isso é o que eu fiz até agora

import datetime
import pandas as pd
import json
from ast import literal_eval

df = pd.DataFrame(data)
df.columns = ["date", "status"]
df = df[df["status"] != '[]'] # remove empty lists
df['status'] = df['status'].apply(literal_eval) # convert string list of list into regular list

Como realizo o próximo conjunto de operações conforme mencionado acima?

Shubham Sharma

Depois de usar literal_evalpara avaliar as strings na coluna statuscomo listas python, você pode usar:

Para a versão pandas, >= 0.25você pode usar explode:

# Explode dataframe
df_out = df.explode('status').reset_index(drop=True)

# fill the NaN with empty lists
df_out['status'] = df_out['status'].dropna().reindex(df_out.index, fill_value=[])

Para a versão pandas < 0.25que explodenão está disponível, você pode replicar o comportamento do tipo explosão usando e index.repeat, em seguida, nivelar as listas aninhadas usando chain:

from itertools import chain

l = df['status'].str.len()
m = l > 0

df_out = df.reindex(df[m].index.repeat(l[m]))
df_out['status'] = list(chain(*df.loc[m, 'status']))
df_out = df_out.append(df[~m]).sort_index().reset_index(drop=True)

>>> df_out

                        date                       status
0 2021-02-06 08:18:01.212763     [London, New York, BUSY]
1 2021-02-06 08:17:01.018633        [Mumbai, Tokyo, IDLE]
2 2021-02-06 08:16:01.182888   [Amsterdam, Chicago, IDLE]
3 2021-02-06 08:16:01.182888    [Amsterdam, London, IDLE]
4 2021-02-06 08:16:01.182888    [Amsterdam, Berlin, BUSY]
5 2021-02-06 08:15:01.245619        [Tokyo, Moscow, IDLE]
6 2021-02-06 07:18:01.413066  [Mumbai, Los Angeles, IDLE]
7 2021-02-06 07:18:01.413066       [Mumbai, Berlin, IDLE]
8 2021-02-06 07:17:01.154138                           []
9 2021-02-06 07:16:01.253111                           []

Este artigo é coletado da Internet.

Se houver alguma infração, entre em [email protected] Delete.

editar em
0

deixe-me dizer algumas palavras

0comentários
loginDepois de participar da revisão

Artigos relacionados

Pandas: filtra as linhas com base em uma coluna contendo listas

Divida uma coluna em várias linhas com base em vários delimitadores no Postgres

como selecionar várias linhas como um grupo com base em uma condição de coluna em pandas

Pandas: crie várias linhas em um df para uma coluna explodida contendo valores de lista

Divida as linhas em várias linhas com base na vírgula: solução de uma linha

Como faço para remover linhas em uma lista contendo matrizes numpy com base em uma condição?

Como contar linhas exclusivas em uma coluna com base em várias condições em python

Divida uma linha DataFrame em várias linhas com base no valor inteiro no Pandas

Divida uma coluna em intervalos regulares em várias linhas

Divida uma coluna em várias colunas com base em várias condições e agrupe por

Como selecionar várias linhas com base em uma coluna

Como selecionar / contar linhas em uma coluna com base em várias condições

Divida a lista de tuplas em uma lista separada com base em uma condição

Divida uma tabela em várias tabelas com base em uma coluna

Pandas, crie uma nova coluna com base em outras colunas em várias linhas

Pyspark - filtre várias linhas com base em uma condição em uma linha

Como combinar várias linhas em uma coluna com pandas?

pandas: retorna um valor de uma coluna da lista com base em uma condição em outra coluna da lista

Crie uma nova coluna com base em uma condição em várias colunas

Como selecionar várias linhas em uma coluna com uma determinada condição

Divida as strings com várias palavras em palavras individuais para a série Pandas contendo uma lista de strings

Divida os valores de uma coluna em várias linhas

Como mesclar várias linhas em uma linha com base em uma coluna com valor específico no Pandas

Retorna uma lista de nomes de colunas como uma nova coluna com base em uma condição em pandas

Converta uma coluna contendo uma lista de dicionários em várias colunas no dataframe do pandas

Divida uma linha contendo intervalo de tempo em várias linhas (questão complicada de sql)

Crie uma nova coluna em pandas com base em valores em várias colunas e na mesma condição

Soma linhas em uma coluna com base em uma condição em R

Python Pandas Dataframe eliminando linhas com base em uma coluna contendo um caractere