Tengo una nporm Pandas DataFrame df define de la siguiente manera. (Sé que esta no es la mejor manera de hacerlo. Tiene sentido lo que estoy tratando de hacer en mi código actual, pero que sería de TMI por este post tan solo tomar mi palabra de que este enfoque funciona en mi particular escenario.)

>>> df = DataFrame(columns=['col1'])
>>> df.append(Series([None]), ignore_index=True)
>>> df
Empty DataFrame
Columns: [col1]
Index: []

Me almacenados en las listas de las células de este DataFrame de la siguiente manera.

>>> df['column1'][0] = [1.23, 2.34]
>>> df
     col1
0  [1, 2]

Por alguna razón, el DataFrame almacenados en esta lista como una cadena en lugar de una lista.

>>> df['column1'][0]
'[1.23, 2.34]'

Tengo 2 preguntas para usted.

  1. ¿Por qué el DataFrame almacenar una lista como una cadena y es allí una manera de evitar este comportamiento?
  2. Si no, entonces hay un Python el camino para convertir esta cadena en una lista?

Actualización

El DataFrame yo estaba usando había sido guardado y cargado de un formato CSV. Este formato, en lugar de la DataFrame sí mismo, convierte la lista a partir de una cadena literal.

  • Puedes publicar algo de código que se reproduce este como dataframes soporte de almacenamiento de cualquier arbritrary el objeto para que se debería haber funcionado.
  • cosa segura.
  • he pandas versión 0.12.0, y no convertir la lista en cadena. ..
  • En la versión 0.13.1 el código da un índice de error, si usted cree que el dataframe pasando los datos inicialmente como listas funciona y, a continuación, asignar una celda con un nuevo valor a la lista de obras, puede imprimir el df antes y después de la asignación de
  • definitivamente.
  • ¿Qué versión de los pandas se está utilizando, usted puede hacer print pandas.version.version
  • 0.12.0. Me pregunto por qué @namit me están consiguiendo resultados diferentes.

InformationsquelleAutor Gyan Veda | 2014-04-16

7 Comentarios

  1. 47

    Como usted ha señalado, esto puede comúnmente ocurren cuando el ahorro y la carga de los pandas DataFrames como .csv archivos, lo cual es un formato de texto.

    En el caso de que esto sucedió debido a que la lista de objetos que tienen una representación de cadena, lo que les permite ser almacenado como .csv archivos. La carga de la .csv luego de rendimiento que la representación de cadena.

    Si desea almacenar los objetos reales, usted debe utilizar DataFrame.to_pickle() (nota: los objetos deben ser picklable!).

    Para responder a su segunda pregunta, usted puede convertir de nuevo con ast.literal_eval:

    >>> from ast import literal_eval
    >>> literal_eval('[1.23, 2.34]')
    [1.23, 2.34]
    • Los Pandas dataframes soporte de almacenamiento de cualquier arbritrary objetos por lo que he trabajado
    • Aparentemente no, porque tengo list convertido a string con to_csv seguido por from_csv en la versión 0.17.1.
  2. 4

    Me encontré con este problema y no hay una solución muy simple (los pandas.eval()). Estoy usando pandas 0.20.0.

    # SETUP
    import pandas as pd
    import io
    
    csv = io.StringIO(u'''
    id  list
    A1  [1,2]
    A2  [3,4]
    A3  [5,6]
    ''')
    
    df = pd.read_csv(csv, delim_whitespace = True)
    
    # TYPE CHECK <type 'str'>
    print type(df.at[0, 'list'])
    
    # MAIN CONVERSION
    df['list'] = pd.eval(df['list'])
    
    # TYPE CHECK <type 'list'>
    print type(df.at[0, 'list'])
  3. 3

    1) no Hay una forma de evitar este comportamiento. Uso loc ayuda aquí.

    >>> import pandas as pd
    
    >>> df = pd.DataFrame(columns=['column1'])
    >>> df = df.append(pd.Series(data = {'column1':[None]}), ignore_index = True)
    
       column1
    0  [None]
    
    >>> # Add list to index 0 in column1
    >>> df.loc[0,'column1'] = [1.23, 2.34]
    >>> print(df.loc[0, 'column1'])
    [1.23, 2.34]

    2) Python el camino para convertir esta cadena en una lista. (Esto es probablemente lo que usted desea como el DataFrame está utilizando había sido guardado y cargado de un formato CSV, hay un par de soluciones para esto). Esta es una adición en pshep123 la respuesta.

    from ast import literal_eval
    import pandas as pd
    
    csv = io.StringIO(u'''
    id  list
    A1  [1,2]
    A2  [3,4]
    A3  [5,6]
    ''')
    df = pd.read_csv(csv, delim_whitespace = True)
    
    # Output is a string
    df.loc[0, 'list']
    '[1,2]'
    
    # Convert entire column to a list
    df.loc[:,'list'] = df.loc[:,'list'].apply(lambda x: literal_eval(x))
    
    # Output is a list
    df.loc[0, 'list']
    [1, 2]
    • Tenga en cuenta que usted no necesita utilizar una función lambda. El apply método se utilizan cada fila de la entrada dentro de la función de pasar.Acaba de escribir .apply(literal_eval). Reserva la lambda para una más complicada de la lógica.
  4. 1

    sólo para referencia… pandas no convertir listas de cadena. ..

    In [29]: data2 = [{'a': [1, 5], 'b': 2}, {'a': 5, 'b': 10, 'c': 20}]                                                                                        
    
    In [30]: df = pd.DataFrame(data2)                                                                                                                           
    
    In [31]: df                                                                                                                                                 
    Out[31]: 
            a   b   c
    0  [1, 5]   2 NaN
    1       5  10  20
    
    In [32]: df['a'][0], type(df['a'][0])                                                                                                                       
    Out[32]: ([1, 5], list)
    
    In [33]: pd.__version__
    Out[33]: '0.12.0'
    • Como he descubierto, a veces pandas convertir una lista en una cadena. Debe tener que ver con la manera en que estoy definiendo este DataFrame o la inserción de datos. Es bueno saberlo para referencia en el futuro.
    • No puedo volver a crear este tema
    • Me lo imaginé! Voy a editar mi pregunta ahora.
  5. 1

    Yo tenía el mismo problema. Al almacenar un dataframe columna de la lista a un archivo CSV utilizando df.to_csv(), las columnas de la lista se convierte en una cadena por ejemplo, «[42, 42, 42]» en lugar de [42, 42, 42]

    Alex respuesta es correcta y que usted puede utilizar literal_eval para convertir la cadena a una lista. El problema con este enfoque es que usted necesita para importar una biblioteca adicionales y usted necesidad de aplicar o asignar la función a su dataframe. Como la manera más fácil, es la fuerza de los Pandas para leer la columna como un objeto de Python (dtype)

    df["col1"].astype('O')

    La junta se utiliza para los objetos de Python, incluidas las listas. Más info aquí. Tenga en cuenta que este método no funciona si se analiza vacía de la lista de cadenas: «[]»

    Alternativamente, usted puede también aplicar una función a la columna (esto es para enteros):

    def stringToList(string):
        # input format : "[42, 42, 42]" , note the spaces after the commas, in this case I have a list of integers
        string = string[1:len(string)-1]
        try:
            if len(string) != 0: 
                tempList = string.split(", ")
                newList = list(map(lambda x: int(x), tempList))
            else:
                newList = []
        except:
            newList = [-9999]
        return(newList)
    
    df["col1"] = df["col1"].apply(lambda x: stringToList(x))
  6. 0

    Puede utilizar directamente pandas –

    df = pd.read_csv(df_name, converters={'column_name': eval})

    Esto va a leer esa columna como su correspondiente dtype en python en lugar de una cadena.

  7. 0

    Un simple hack que se usa para llamar a una función lambda que los índices de la primera y la última elementos (la lista entre corchetes en str) y llama al método split, seguido por otro que reemplaza los elementos de la lista con ints.

    df['column1'] = df['column1'].apply(lambda x:x[1:-1].split(',')).apply(lambda x:[int(i) for i in x])

Dejar respuesta

Please enter your comment!
Please enter your name here