<jupyter_start><jupyter_text>View GDSC UNI          Run in Google Colab           View source on GitHub  PFDS6: Concatenaciones y Merge  Concatenaciones Una concatenación es encadenar conceptos, ideas, números o códigos para crear una secuencia o conjunto interconectado. Esta idea de concatenación puede ser implementado en python con numpy y panda dependiendo del tipo de dato con el que nos encontramos trabajando. Usaremos numpy cuando queremos concatenar arrays y pandas cuando queremos concatenar Series o DataFrames.En numpy, las concatenaciones se realizan mediante el método *concatenate* y agregando como parámetros las matrices a concatenar, la concatenación se puede hacer por columnas o por filas especificando el axis.<jupyter_code>import numpy as np
import pandas as pd
x_1 = np.array([[np.random.randint(0,20) for j in range(4)] for i in range(3)])  
x_2 = np.array([[np.random.randint(0,20) for j in range(4)] for i in range(3)])
print('-'*30 +'x_1'+'-'*30 )
print(x_1)
print('-'*30 +'x_2'+'-'*30 )
print(x_2)
np.concatenate([x_1, x_2])
np.concatenate([x_1, x_2]).shape
np.concatenate([x_1, x_2], axis=1)
np.concatenate([x_1, x_2], axis=1).shape<jupyter_output><empty_output><jupyter_text>En Pandas, las concatenaciones se hacen mediante el método *concat*. A diferencia de las concatenaciones en numpy, en Pandas se respetan los índices al momento de realizar las concatenaciones. Como se mencionó anteriormente, estas concatenaciones se realizan con las series o DataFrame.<jupyter_code>s1 = pd.Series(x_1[0], index=['PC1', 'PC2', 'PC3', 'PC4'])
s2 = pd.Series(x_2[0], index=['PC1','PC2','PC3','PC4'])
print('-'*30 +'s1'+'-'*30 )
print(s1)
print('-'*30 +'s2'+'-'*30 )
print(s2)
pd.concat([s1,s2])
pd.concat([s1, s2], axis=1)<jupyter_output><empty_output><jupyter_text>Para realizar concatenaciones sin importar los índices, debemos de agregar como parámetros las series sin los índices, para esto usamos el método *reset_index*.<jupyter_code>s1.reset_index(drop=True)
pd.concat([s1.reset_index(drop=True), s2.reset_index(drop=True)], axis=1)<jupyter_output><empty_output><jupyter_text>Los DataFrame no son muy ajenos a las series en cuanto a las concatenaciones, la única diferencia es que tenemos que ingresar como parámetros las columnas y los índices.<jupyter_code>pd.options.display.float_format = '{:,.2f}'.format
df1 = pd.DataFrame(np.random.rand(3,4)*20, columns=['PC1', 'PC2', 'PC3', 'PC4'],index=['Alejandro', 'Ruben', 'Fernanda'])
df1
df2 = pd.DataFrame(np.random.rand(3,4)*20, columns=['PC1', 'PC2', 'PC3', 'PC4'],index=['Mariana', 'Mauricio', 'Fernanda'])
df2
pd.concat([df1, df2])
pd.concat([df1, df2], axis=1)<jupyter_output><empty_output><jupyter_text>Al agregarle a la concatenación el parámetro *join='inner'* nos da como retorno la concatenación de las filas que tienen en común los DataFrame.<jupyter_code>pd.concat([df1, df2], axis=1, join='inner')
pd.concat([df1.reset_index(drop=True), df2.reset_index(drop=True)], axis=1)<jupyter_output><empty_output><jupyter_text>Una forma más acortada de realizar las concatenaciones es usando *append*.<jupyter_code>df1.append(df2)
df1.append(df2).append(df2)
df1.T.append(df2.T).T<jupyter_output><empty_output><jupyter_text>Merge Si nuestro objetivo no es solo concatenar sino que queremos fusionar nuestros datos en un solo DataFrame, el método correcto a usar es *merge()* Para conocer más acerca de él, crearemos un DataFrame llamado df_left y otro llamado df_right, los cuales vamos a fusionar en un solo DataFrame.<jupyter_code>df_left = pd.DataFrame(
    {'X':['x0','x1','x2','x3'],
    'W':['w0','w1','w2','w3'],
    'Y':['y0','y1','y2','y3'],
    'Mix':['y2','y3','a2','a3']},
    index = ['y2','y3','a2','a3'])
df_left
df_right = pd.DataFrame(
    {'Z':['z2','z3','z4','z5'],
     'A':['a2','a3','a4','a5'],
     'Y':['y2','y3','y4','y5']},
    index = [2,3,4,5])
df_right
pd.merge(df_left, df_right)<jupyter_output><empty_output><jupyter_text>Al hacer Merge, este tiene por defecto los siguientes parámetros *how="inner"*, el cual indica que obtendremos la intersección de los DataFrames y 'on' que indica en qué nivel de columna o índice se hará la unión, este valor, debe encontrarse en ambos DataFrames para que se pueda hacer el merge, el valor predeterminado de este son todos los índices o columnas en los que existan coincidencias.<jupyter_code>pd.merge(df_left, df_right, how='inner', on='Y')<jupyter_output><empty_output><jupyter_text>Si usamos el parámetro *left_on* especificamos el nombre de nivel o índice para unir el DataFrame izquierdo y con *right_on*, especificamos el nombre de nivel de columna o índice para unir el DataFrame Derecho. Como ejemplo haremos un merge en el que uniremos las coincidencias en cuanto a los valores de la columna Mix con la columna Y y después con la columna A.<jupyter_code>pd.merge(df_left, df_right, how='inner', left_on='Mix', right_on='Y')
pd.merge(df_left, df_right, how='inner', left_on='Mix', right_on='A')<jupyter_output><empty_output><jupyter_text>Podemos especificar el cómo queremos el merge mediante el parámetro *how*, como se mencionó anteriormente, este tiene por defecto la intersección (inner). A continuación se muestra un gráfico con las diferentes formas de hacer el merge y el valor del parámetro *how* para cada caso.<jupyter_code>df_left = pd.DataFrame(
    {'X':['x0','x1','x2','x3'],
    'W':['w0','w1','w2','w3'],
    'Y':['y0','y1','y2','y3']},
     index = [0,1,2,3])

df_left
pd.merge(df_left, df_right, how='inner', on='Y')
pd.merge(df_left, df_right, how='left', on='Y')
pd.merge(df_left, df_right, how='right', on='Y')
pd.merge(df_left, df_right, how='outer', on='Y')<jupyter_output><empty_output><jupyter_text>Por último, el parámetro *on* puede recibir un solo valor o una lista tal como mostrará en el ejemplo siguiente, además podemos modificar los sufijos que se generan al hacer un merge con el parámetro *suffixes*.<jupyter_code>df_left = pd.DataFrame(
                      {'X': ['x0', 'x1', 'x2', 'x3'],
                        'W': ['w0', 'w1', 'w2', 'w3'], 
                        'Y': ['y0', 'y1', 'y2', 'y3'],
                        'A': ['a0', 'a1', 'a2', 'a3'],})
df_left
pd.merge(df_left, df_right, how='outer', on=['Y','A'])
pd.merge(df_left, df_right, how='outer', on='A', suffixes=['_left','_right'])<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14852894653590637, 'fraction_numerical': 0.027997469155330593, 'mean_word_length': 5.769807280513919, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '638203', 'license': 'MIT', 'n_tokens_mistral': 2408, 'n_tokens_neox': 2365, 'n_words': 658, 'path': 'PFDS6_Concatenaciones_y_Merge.ipynb', 'repo_name': 'GDSC-UNI/Pandas-For-Data-Science', 'size': '6322'}