python - pydata - pandas subset
Cómo crear un DataFrame de Pandas a partir de una cadena (2)
Para probar alguna funcionalidad, me gustaría crear un DataFrame
partir de una cadena. Digamos que mis datos de prueba se ven así:
TESTDATA="""col1;col2;col3
1;4.4;99
2;4.5;200
3;4.7;65
4;3.2;140
"""
¿Cuál es la forma más sencilla de leer esos datos en un DataFrame
datos de Pandas?
Un CSV de ancho variable tradicional no se puede leer para almacenar datos como una variable de cadena. Considere datos de ancho fijo separados por tubería en su lugar. Varios IDEs y editores pueden tener un complemento para formatear el texto separado por tuberías en una tabla ordenada.
El siguiente funciona para mi. Para usarlo, guárdelo en un archivo llamado pandas_util.py
y llame a read_pipe_separated_str(str_input)
. Un ejemplo está incluido en el docstring de la función.
import io
import re
import pandas as pd
def _prepare_pipe_separated_str(str_input):
substitutions = [
(''^ *'', ''''), # Remove leading spaces
('' *$'', ''''), # Remove trailing spaces
(r'' */| *'', ''|''), # Remove spaces between columns
]
if all(line.lstrip().startswith(''|'') and line.rstrip().endswith(''|'') for line in str_input.strip().split(''/n'')):
substitutions.extend([
(r''^/|'', ''''), # Remove redundant leading delimiter
(r''/|$'', ''''), # Remove redundant trailing delimiter
])
for pattern, replacement in substitutions:
str_input = re.sub(pattern, replacement, str_input, flags=re.MULTILINE)
return str_input
def read_pipe_separated_str(str_input):
"""Read a Pandas object from a pipe-separated table contained within a string.
Example:
| int_score | ext_score | automation_eligible |
| | | True |
| 221.3 | 0 | False |
| | 576 | True |
| 300 | 600 | True |
The leading and trailing pipes are optional, but if one is present, so must be the other.
In PyCharm, the "Pipe Table Formatter" plugin has a "Format" feature that can be used to neatly format a table.
"""
str_input = _prepare_pipe_separated_str(str_input)
return pd.read_csv(pd.compat.StringIO(str_input), sep=''|'')
Una forma simple de hacerlo es usar StringIO
y pasarlo a la función pandas.read_csv
. P.ej:
import sys
if sys.version_info[0] < 3:
from StringIO import StringIO
else:
from io import StringIO
import pandas as pd
TESTDATA = StringIO("""col1;col2;col3
1;4.4;99
2;4.5;200
3;4.7;65
4;3.2;140
""")
df = pd.read_csv(TESTDATA, sep=";")