Manipulación de datos con Python usando Pandas

Pandas fue desarrollado en el fondo de cobertura AQR por wes mckinney para permitir un análisis rápido de los datos financieros. Pandas es una extensión de NumPy que admite operaciones vectorizadas que permiten una manipulación rápida de la información financiera.

Usaré los datos de la empresa proporcionados por un Zona de pruebas para desarrolladores de Intrinio. Si desea seguir adelante, puede encontrar el código y los datos en el Analizando Alpha Github Repo.

import pandas as pd
import numpy as np
import urllib.request
url= 'https://raw.githubusercontent.com/leosmigel ...
  /analyzingalpha/master/2019-09-30-data-manipulation-with-python/companies.csv'
with urllib.request.urlopen(url) as f:
  companies = pd.read_csv(f, index_col='id')
companies[['name', 'sector']].head()
        name	                 sector
id
1	Apple Inc                Consumer Goods
2	American                Express Co Financial
3	Boeing Co              Industrial Goods
4	Caterpillar Inc	       Industrial Goods
5	Cisco Systems Inc Technology

Cómo hacer que sus datos estén ordenados

Si bien no es necesario para estos ejemplos simples, quiero presentar Tidy Data. Cuando trabaje con grandes conjuntos de datos, y especialmente para el análisis factorial, querrá hacer su vida más fácil y ordenar su conjunto de datos usando pandas.melt. Hace que los datos sean más fáciles de analizar y, por lo general, más eficaces. Para aquellos que estén interesados, hay un gran artículo sobre medio en Poner en orden el conjunto de datos en Python.

Operaciones de cadenas en Pandas

A menudo, necesitaremos manipular datos de cadenas que tienen un formato incorrecto. pandas proporciona [vectorized string operations/python-for-finance#vectorization). For most string operations, you’ll need to be familiar with regular expressions.

Let’s perform an example extract operation by smushing some of our existing data together.

companies_smushed = pd.DataFrame()
companies_smushed['sector_employees'] = empresas['sector'] + \ empresas['employees'].astype(str) print(empresas[['sector', 'employees']].head()) print(companies_smushed.head()) empresas_smushed = empresas_smushed['sector_employees'].str.extract(r'(\D+)(\d+)') empresas_aplastadas.cabeza()
    sector                          employees
0   Consumer Goods      132000
1   Financial                    59000
2   Industrial Goods        153027
3   Industrial Goods        104000
4   Technology                74200

    sector_employees
0   Consumer Goods      132000
1   Financial                    59000
2   Industrial Goods        153027
3   Industrial Goods        104000
4   Technology                74200

0   1
0   Consumer Goods    132000
1   Financial                  59000
2   Industrial Goods      153027
3   Industrial Goods      104000
4   Technology              74200

Operaciones de agrupación: dividir-aplicar-combinar

Las operaciones de agrupación se pueden dividir en tres pasos:

  • Dividir los datos en grupos
  • Aplicar una función a cada grupo
  • Combinar los grupos en un resultado.
  • Antes de usar pandas para agrupar y modificar nuestros datos, veamos cómo podríamos lograr contar el número de empresas en cada sector usando python.

    sector_count = {}
    for sector in companies['sector']:
      if sector_count.get(sector):
        sector_count.update({sector: sector_count[sector] + 1})
      else:
        sector_count.update({sector: 1})
    print(sector_count)
    {'Consumer Goods': 4,
    'Financial': 5,
    'Industrial Goods': 5,
    'Technology': 5,
    'Basic Materials': 2,
    'Services': 3,
    'Healthcare': 4}

    Agrupamiento

    pandas.Dataframe.groupby nos da una mejor manera de agrupar datos. groupby devuelve un objeto DataFrameGroupBy o SeriesGroupBy. Estos objetos se pueden considerar como un grupo. Puede ver a continuación que sector_group.groups devuelve un diccionario de pares clave/valor que son sectores y sus filas asociadas. Vea a continuación que el grupo financiero contiene filas ([1, 6, 8, 14, 23]) respectivamente.

    sector_group = companies.groupby(by='sector')
    print(sector_group)
    print(sector_group.groups)
    print(sector_group.get_group('Financial'))
    <pandas.core.groupby.generic.DataFrameGroupBy object at 0x7f2a7853b828>
    
    {'Basic Materials': Int64Index([5, 27], dtype='int64'),
    'Consumer Goods': Int64Index([0, 15, 20, 22], dtype='int64'),
    'Financial': Int64Index([1, 6, 8, 14, 23], dtype='int64'),
    'Healthcare': Int64Index([13, 18, 21, 24], dtype='int64'),
    'Industrial Goods': Int64Index([2, 3, 7, 12, 17], dtype='int64'),
    'Services': Int64Index([9, 16, 26], dtype='int64'),
    'Technology': Int64Index([4, 10, 11, 19, 25], dtype='int64')}
    
        id                     name  ...                   industry_group                                employees
    1    2      American Express Co  ...       Credit Services                                59000
    6   25                 Visa Inc  ...                 Credit Services                                17000
    8    8  Goldman Sachs Group Inc  ...    Investment Brokerage - National    36600
    14  13      JPMorgan Chase & Co  ...    Money Center Banks                      256105
    23  22  Travelers Companies Inc  ...     Property & Casualty Insurance       30400
    
    [5 rows x 7 columns]

    Para mostrar que el objeto groupby es solo un modelo, podemos replicar get_group usando iloc.

    print(companies.iloc[[1,6,8,14,23],[1,5,6]])
                           name                        industry_group                            employees
    1       American Express Co            Credit Services                            59000
    6       Visa Inc                                  Credit Services                            17000
    8       Goldman Sachs Group Inc    Investment Brokerage - National 36600
    14     JPMorgan Chase & Co          Money Center Banks                   256105
    23     Travelers Companies Inc       Property & Casualty Insurance    30400

    En resumen, groupby crea un modelo que nos permite ejecutar muchas operaciones útiles en el grupo. Usar un objeto groupby es eficiente ya que nos permite tener una relación de uno a muchos con respecto al cálculo de valores de grupo.

    Alternativamente, podemos usar el poder de Pandas y usar la indexación booleana y un método de agregación para devolver el número de empresas en cada sector.

    Agregación

    La agregación toma los valores y devuelve un valor de una dimensión menor. Por ejemplo, una función que toma una serie y devuelve un único valor escalar. Cada agregación de GroupBy, ya sea implícita o explícitamente, tiene una columna de agrupación, una columna de agregación y una columna de función. Las funciones de agregación comunes se muestran a continuación: Función Descripción media () Calcular la media de los grupos suma () Calcular la suma de los valores del grupo tamaño () Calcular los tamaños de los grupos contar () Calcular el recuento de los grupos td () Desviación estándar de los grupos var () Calcular la varianza de los grupos sem () Error estándar del media de gruposdescribe()Genera estadísticas descriptivasfirst()Calcula el primero de los valores del grupolast()Calcula el último de los valores del gruponth()Toma el valor enésimo, o un subconjunto si n es una listamin()Calcula el mínimo de los valores del grupomax()Calcula el máximo de los valores del grupo

    print(sector_group.size())
    print(sector_group.size().sum())
    sector
    Basic Materials       2
    Consumer Goods   4
    Financial                 5
    Healthcare              4
    Industrial Goods     5
    Services                 3
    Technology             5
    dtype: int64
    28

    También podemos agrupar por varias columnas. Observe que la función de agregación se invocó automáticamente en la columna de empleados, ya que es la única columna de tipo numérico.

    companies.groupby(['sector', 'industry_group'])['employees'].sum()
    sector                       industry_group
    Basic Materials         Major Integrated Oil & Gas                          119600
    Consumer Goods     Beverages - Soft Drinks                               62600
                                     Electronic Equipment                                   132000
                                     Personal Products                                       92000
                                     Textile - Apparel Footwear & Accessories    73100
    Financial                   Credit Services                                            76000
                                     Investment Brokerage - National                 36600
                                     Money Center Banks                                   256105
                                     Property & Casualty Insurance                    30400
    Healthcare                Drug Manufacturers - Major                        296500
                                     Health Care Plans                                       300000
    Industrial Goods       Aerospace/Defense Products & Services   393027
                                     Diversified Machinery                                  376516
                                     Farm & Construction Machinery                  104000
    Services                   Discount, Variety Stores                              2200000
                                     Home Improvement Stores                          413000
                                     Restaurants                                                 210000
    Technology               Business Software & Services                    131000
                                     Information Technology Services                350600
                                     Networking & Communication Devices       74200
                                     Semiconductor - Broad Line                       107400
                                     Telecom Services - Domestic                     144500
    Name: employees, dtype: int64 

    pandas.core.groupby.DataFrame.agg nos permite realizar múltiples agregaciones a la vez, incluidas las agregaciones definidas por el usuario.

    def half(column):
      return column.sum() / 2
    
    def total(column):
      return column.sum()
    
    companies.groupby(['sector']).agg({'employees': [np.min, half, total]})
                                               employees
                                       amin	   half	          total
    sector
    Basic Materials        48600	  59800.0     119600
    Consumer Goods    62600	  179850.0	  359700
    Financial                  17000	  199552.5	  399105
    Healthcare               69000	  298250.0	  596500
    Industrial Goods      93516	  436771.5	  873543
    Services                  210000  1411500.0	2823000
    Technology              74200	  403850.0	  807700

    Transformación

    La transformación devuelve datos manipulados en el mismo tamaño que los datos pasados. Hay muchos métodos y funciones a su disposición para transformar datos, como se muestra a continuación. Método / Función Descripción Serie. mapa Sustituir cada valor por otro Serie. aplicar Invocar una función por elementos en una serie DataFrame. rowSeries.transformInvoca una función que devuelve una serie de valores transformadosDataFrame.transformInvoca una función que devuelve un marco de datos de valores transformadospandas.meltReforma un marco de datos. Útil para graficar, operaciones vectorizadas y ordenar datos.pandas.pivotRemodelar un marco de datos. Esencialmente una operación sin fundir.

    En el siguiente ejemplo, pasamos una función definida find_percent y devolvemos la serie transformada.

    def find_percent(column):
      return column / float(column.sum())
    companies.groupby('sector').agg({'employees': 'sum'}).transform(find_percent)
    	employees
    sector
    Basic Materials	      0.020003
    Consumer Goods	  0.060159
    Financial	                0.066749
    Healthcare	              0.099763
    Industrial Goods      0.146098
    Services	                0.472141
    Technology	            0.135086

    Al igual que con agg, podemos pasar múltiples funciones, incluidas funciones lambda.

    companies.groupby('sector').agg({'employees':'sum'}).transform([lambda x: x / x.sum()])
    	  employees
                                  <lambda>
    sector
    Basic Materials       0.020003
    Consumer Goods   0.060159
    Financial                 0.066749
    Healthcare              0.099763
    Industrial Goods     0.146098
    Services                 0.472141
    Technology             0.135086
    

    Si bien no podemos pasar múltiples funciones para aplicar como podemos con transform, podemos acceder a otras columnas usando apply donde estamos limitados con transform. Nuevamente, es mejor saber qué está disponible para usted y usar la mejor herramienta para el trabajo en ese momento actual.

    companies.groupby('sector').apply(lambda x: x['employees'] * 2)
    sector
    Basic Materials        5       97200
                                    27     142000
    Consumer Goods    0      264000
                                    15     125200
                                    20     146200
                                    22     184000
    Financial                  1      118000
                                    6       34000
                                    8       73200
                                    14     512210
                                    23      60800
    Healthcare               13     270200
                                    18     138000
                                    21     184800
                                    24     600000
    Industrial Goods      2      306054
                                    3      208000
                                    7      566000
                                    12     480000
                                    17     187032
    Services                  9      826000
                                   16     420000
                                   26    4400000
    Technology             4      148400
                                   10     701200
                                   11     214800
                                   19     262000
                                   25     289000
    Name: employees, dtype: int64

    Filtración

    El filtro devuelve un subconjunto de los datos originales. Funciona de manera similar a la indexación booleana, excepto que en lugar de trabajar en filas individuales, funciona en grupos individuales. El filtro debe devolver un valor verdadero o falso para el grupo como un todo. El sector servicios es el único sector que cuenta con más de 1.000.000 de empleados.

    companies.groupby('sector').filter(
        lambda x: x['employees'].sum() > 1000000
        )[['name', 'employees']]
    name	                           employees
    id
    9	Home Depot Inc       413000
    15	McDonalds Corp    210000
    27	Walmart Inc            2200000

    Tablas dinamicas

    Podemos producir los mismos datos en un formato diferente usando pandas.pivot_table.

    companies.pivot_table(columns='sector', values='employees', aggfunc='sum')
    sector         Basic Materials      Consumer Goods ...
    employees 119600                   359700

    Unión de datos

    Podemos unir rápidamente dos marcos de datos a través de unir, fusionar y concatenar. Merge es la función subyacente para todos los comportamientos de unión/fusión. Unirse tiene valores predeterminados ligeramente diferentes y se proporciona como un método conveniente.

    Veamos un ejemplo en acción incorporando los datos de seguridad y uniéndonos en la columna de identificación.

    import pandas as pd
    import numpy as np
    import urllib.request
    url= 'https://raw.githubusercontent.com/leosmigel ...
      /analyzingalpha/master/data-manipulation-with-python/securities.csv'
    with urllib.request.urlopen(url) as f:
      securities = pd.read_csv(f, index_col='id')
    print(securities.head())
    securities_companies = companies.join(securities)
    securities_companies[['name', 'ticker', 'figi']].head(7)
            ticker      currency       figi
    id
    1      AAPL      USD             BBG000B9Y5X2
    2      AXP        USD             BBG000BCR153
    3      BA          USD             BBG000BCSV38
    4      CAT        USD             BBG000BF0LJ6
    5      CSCO    USD             BBG000C3JBN9
             name                            ticker         figi
    id
    1       Apple Inc                       AAPL    BBG000B9Y5X2
    2       American Express Co	 AXP      BBG000BCR153
    3       Boeing Co                     BA         BBG000BCSV38
    4       Caterpillar Inc               CAT       BBG000BF0LJ6
    5       Cisco Systems Inc        CSCO   BBG000C3JBN9
    6       Chevron Corp               CVX      BBG000K4NHJ5
    25     Visa Inc                         V           BBG000PSL0X0

    Deja un comentario